Frame Grabber - Working Code

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Frame Grabber - Working Code

#1 Post by Bill Legge » 02 Aug 2021 07:46

Again, nothing clever. but good sound working code on a PIC18F8722 to receive a stream of ASCII bytes after a 'header.'
In this case the header is 'DATA' followed by the bytes.
Displays the bytes on an LCD and on the USART Terminal monitor.
Same terminal monitor may be used to test the code sending 'DATA12345' every few mS.

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Project:         Frame_Grabber                                             //
// File:            Frame_Grabber.c                                           //
// Function:        Detect and decode incoming RS232 form a telemetry link    //
// MCU:             PIC18F8722                                                //
// Board:           BigPIC5                                                   //
// Power            5V.                                                       //
// Compiler:        mikroC PRO for PIC version 7.6.0                          //
// Programmer:      On board                                                  //
// Author:          WVL                                                       //
// Date:            August 2021                                               //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Notes                                                                      //
// Detect a frame header and following data from a RS232 stream               //
// Frame Header is 'DATA'                                                     //
// Followed by unsigned 8 bit bytes                                           //
// Select mikroE libraries: C_type, LCD, Printout, UART                       //
// Uses UART2 in PIC18F8722                                                   //
// displays byte[1] on the LCD and all bytes in the USATRT monitor            //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Data formats                                                               //
// Remember that RS232 sends the ASCII code for a character                   //
// So the value '3' is sent in ASCII as '51'                                  //
// This OK for display on LCD but needs conversion to get numerical value     //
// easiest way is to subtract 48                                              //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Test using the Mikro USART Terminal set to 9600Baud                        //
// And 'repeat' send 'DATA12345 to UART2                                      //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Defines and includes - flash some LEDS so you can follow the detection     //
#define LED0 LATB0_bit  // on receipt of a byte                               //
#define LED1 LATB1_bit  // when the frame header 'DATA' has arrived           //
#define LED2 LATB2_bit  // when the correct number of bytes has been received //
#define LED7 LATB7_bit  // looping                                            //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// LCD module connections on Mikro adapter on PORTF                           //
sbit LCD_RS at RF2_bit;                                                       //
sbit LCD_EN at RF3_bit;                                                       //
sbit LCD_D4 at RF4_bit;                                                       //
sbit LCD_D5 at RF5_bit;                                                       //
sbit LCD_D6 at RF6_bit;                                                       //
sbit LCD_D7 at RF7_bit;                                                       //
sbit LCD_RS_Direction at TRISF2_bit;                                          //
sbit LCD_EN_Direction at TRISF3_bit;                                          //
sbit LCD_D4_Direction at TRISF4_bit;                                          //
sbit LCD_D5_Direction at TRISF5_bit;                                          //
sbit LCD_D6_Direction at TRISF6_bit;                                          //
sbit LCD_D7_Direction at TRISF7_bit;                                          //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Global variables                                                           //
unsigned char    rx_byte[5]; // bytes received                                //
unsigned char  data_length=5; // number of bytes received                     //
bit                GOOD_DATA; // set in UART2 ISR cleared in main loop        //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// ISR for HIGH priority interrupts to 0x0008                                 //
// on PIC18s all interrupts jump to the same place so need to test source     //
// Global variables: rx_byte, rx_length, good_data                            //
// Variables must be static to retaing their valve                            //
void high_priority_int() iv 0x0008 ics ICS_AUTO {                             //
    static unsigned char      rxtemp=0;   // last character rx from base      //
    static unsigned short lock_state=0;   // inc after good ID character      //
    static unsigned short          x=0;   // array counter                    //
    static unsigned short     got_id=0;   // TRUE after all ID received       //
    // Test if UART2 has received a character.                                //
    if(RC2IF_bit){                                                            //                                                                              //
        // writing '0' clears errors                                          //
        RCSTA2.OERR= 0;                                                       //
        RCSTA2.FERR= 0;                                                       //                                                                             //
        // Receive a character                                                //
        rxtemp = UART2_Read();                                                //
        LED0 = ~LED0;                                                         //
        // 'DATA' data header has been received so start filling array        //
        if(got_id==1){                                                        //
            LED1 = 1;                                                         //
            rx_byte[x] = rxtemp;                                              //
            x++;                                                              //
        }                                                                     //
                                                                              //
        // Array is full so declare good data and zero got_id and x           //
        if(x==data_length){                                                   //
            LED0 = 0;                                                         //
            LED1 = 0;                                                         //
            LED2 = 1;                                                         //
            got_id = 0;                                                       //
            x=0;                                                              //
            GOOD_DATA = 1;                                                    //
        }                                                                     //
                                                                              //
        // Search for id = 'DATA' and if found set got_id                     //
        if      (rxtemp== 'D' && lock_state == 0)lock_state++;                //
        else if (rxtemp== 'A' && lock_state == 1)lock_state++;                //
        else if (rxtemp== 'T' && lock_state == 2)lock_state++;                //
        else if (rxtemp== 'A' && lock_state == 3)got_id=1;                    //
        else lock_state = 0;  // id wrong so reset combination                //
                                                                              //
        RC2IF_bit = 0;        // clear interrupt flag                         //
    }                                                                         //                                                                              //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////


void main() {
    // Block variables
    unsigned char n = 0;    // re-usable
    // Init
    ADCON1 = 0b00001111;    // all digital
    CMCON  = 0b00000111;    // disable comparators
    INTCON2.RBPU = 1;       // PORTB pullups disabled
    // init ports
    TRISA = 0b00000000;     //
    TRISB = 0b00000000;     // LEDs
    TRISC = 0b00000000;     //
    TRISD = 0b00000000;     //
    TRISE = 0b00000000;     //
    TRISF = 0b00000000;     // LCD
    TRISG = 0b00000000;     // UART2
    TRISH = 0b00000000;     //
    TRISJ = 0b00000000;     //
    // Init peripherals
    Lcd_Init();
    Lcd_Cmd(_LCD_CURSOR_OFF);
    UART1_Init(9600);       // unused
    UART2_Init(9600);       // data stream from radio
    // Set interrupts
    RC2IP_bit  = 1;         // EUSART2 rx interrupt is high priority
    RC2IE_bit  = 1;         // EUSART2 rx interrupt is enabled
    IPEN_bit   = 1;         // priority levels are enabled
    GIEH_bit   = 1;         // enable all high priority interrupts
    GIEL_bit   = 1;         // enable all low priority interrupts
    // Set flags
    GOOD_DATA = 0;          // set in UART2 interrupt

    // Announce
    for(n=0;n<10;n++){LED7   = ~LED7;delay_ms(200);}
    Lcd_Out(1,1,"Frame Grabber");
    Lcd_Out(2,1,"PIC18F8722 40MHz");
    delay_ms(1000);
    LCD_Cmd(_LCD_CLEAR);


    while(1){
        // Deal with rx data and ecode the received bytes whilst UART1
        // interrupt is disabled
        if(GOOD_DATA==1){
            // Clear the flag
             Lcd_Out(1,1,"Good Data");
            GOOD_DATA = 0;
            LED2      = 0;
            Lcd_Chr(2,1,rx_byte[0]);
            for(n=0;n<=(data_length-1);n++){
                UART2_Write(rx_byte[n]);
                UART2_Write(13);
                UART2_Write(10);
            }
        }
        else  Lcd_Out(1,1,"Bad Data ");

        // Hang around a bit
        delay_ms(1000);
        LED7   = ~LED7;
    }
}
Regards Bill Legge in Australia

Post Reply

Return to “User Projects”