///////////////////////////////////////////////////////////////////////// //// PIC_PARSER.C //// //// //// //// This program shows how to implement a serial parser. //// //// Help and example code from the Circuit Cellar article: //// //// "Ham Radio Repeater Locator" - Glen Worstell //// //// http://www.circuitcellar.com/library/print/0804/Worstell_169/ //// //// Worstell-169.pdf //// //// Author : Gerard Sequeira //// /// Feb 27,2007 //// ///////////////////////////////////////////////////////////////////////// #include <16F876A.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) char scar; //current character on the serial port char parse_needle; //parser pointer in parseString char dir_needle; //direction pointer char steer_needle; //steering angle pointer char speed_needle; //speed pointer const char parse_thread[]= "$dddtttsss"; //packet format int16 dir; //direction int16 steer; //steering int16 speed; //speed void restart_parser(void) { parse_needle = 0; //needle = pointer dir_needle = 0; steer_needle = 0; speed_needle = 0; dir = 0; steer = 0; speed = 0; } char is_digit() //check if incoming characters are digits { if ((scar < '0') || (scar > '9')) return 0; else return 1; } #int_rda void parser_isr() { static char parsechar; //current parse character in parseString scar = getc(); //dump RX char into serial_char if (scar == '$') { restart_parser(); parse_needle++; } else { parsechar = parse_thread[parse_needle++]; if (parsechar == 0) restart_parser(); else { if ((parsechar >= 'a') && (parsechar <= 'z')) switch(parsechar) { case 'd' : if (!is_digit()) restart_parser(); else dir = dir * 10 + (scar - '0'); break; case 't' : if (!is_digit()) restart_parser(); else steer = steer * 10 + (scar - '0'); break; case 's' : if (!is_digit()) restart_parser(); else speed = speed * 10 + (scar - '0'); break; default : restart_parser(); } else { if (scar != parsechar) restart_parser(); } } } } void main() { enable_interrupts(global); enable_interrupts(int_rda); output_high(PIN_B3); delay_ms(500); output_low(PIN_B3); delay_ms(500); output_high(PIN_B3); delay_ms(500); output_low(PIN_B3); delay_ms(500); restart_parser(); //initialise all values to zero while(1) { printf("Dir : %ld %ld %ld\n\r",dir,steer,speed); } }