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;
}
}