code:interrupt_driven_nmea
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
code:interrupt_driven_nmea [2008/04/12 19:07] – laurenceb | code:interrupt_driven_nmea [2013/04/18 20:00] (current) – Reports code isn't tested so just put a notice on there upu | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | This is a rather unconvensional approach | + | **This code hasn't been tested and is believe not to work** |
- | <code c> | + | This is a rather unconvensional approach to a NMEA parser - completely based on an ISR to parse the incoming bytes. It uses 1.9KB of code space and 44 bytes of RAM. Should run in less than 10us at 18MHz. |
- | #include " | + | |
- | #include " | + | |
- | #include " | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include <string.h> | + | |
- | #include < | + | |
+ | <code c># | ||
+ | //global(s) | ||
+ | extern gps_type Gps; | ||
+ | |||
// Interrupt driven NMEA parser for Atmel AVR | // Interrupt driven NMEA parser for Atmel AVR | ||
- | //header file starts here | + | |
- | #define minutes | + | ISR(USART_RX_vect) //UART interrupt on mega xx8 series |
- | #define baudrate 4800 | + | |
- | + | ||
- | struct | + | |
- | { | + | |
- | volatile float longitude; | + | |
- | volatile float latitude; | + | |
- | volatile float altitude; | + | |
- | volatile float speed; | + | |
- | volatile float heading; | + | |
- | volatile u08 packetflag; | + | |
- | volatile u08 status; | + | |
- | } gps; | + | |
- | //end of header file | + | |
- | + | ||
- | int main() | + | |
- | { | + | |
- | outb(UCSR0B, | + | |
- | u16 bauddiv = ((F_CPU+(baudrate*8L))/ | + | |
- | outb(UBRR0L, | + | |
- | outb(UBRR0H, | + | |
- | } | + | |
- | + | ||
- | SIGNAL(SIG_USART_RECV) //UART interrupt on mega xx8 series | + | |
{ | { | ||
- | static char buffer[5]; | + | static char buffer[6]; |
static u08 GGA; | static u08 GGA; | ||
static u08 RMC; | static u08 RMC; | ||
Line 47: | Line 20: | ||
static u08 bufferindex; | static u08 bufferindex; | ||
static u08 pointcount; | static u08 pointcount; | ||
+ | static gps_type gps; | ||
char c=UDR0; | char c=UDR0; | ||
switch(c) | switch(c) | ||
Line 52: | Line 26: | ||
case ' | case ' | ||
commacount=0; | commacount=0; | ||
- | bufferindex=0; | ||
- | pointcount=0; | ||
- | stage=0; | ||
- | memset(buffer,' | ||
GGA=FALSE; | GGA=FALSE; | ||
- | RMC=FALSE; //we dont know what sort of packet it is yet | + | RMC=FALSE; //we dont know what sort of packet it is yet |
- | break; | + | case ',': |
- | case ',': | + | commacount++; |
- | commacount++; | + | bufferindex=0; |
- | bufferindex=0; | + | |
pointcount=0; | pointcount=0; | ||
- | stage=0; | + | stage=FALSE; |
+ | memset(buffer,' | ||
break; | break; | ||
case ' | case ' | ||
- | pointcount++; | + | pointcount++; |
- | // break; | + | break; |
- | default: //we have some of the CSV data | + | default: //we have some of the CSV data |
- | buffer[bufferindex]=c; | + | |
+ | { | ||
+ | buffer[bufferindex]=c; | ||
+ | } | ||
if(GGA) | if(GGA) | ||
{ | { | ||
- | if(commacount==2) //the latitude from the GGA | + | switch(commacount) |
- | { | + | { |
- | if(bufferindex< | + | case 3: //the latitude from the GGA |
- | { | + | |
+ | | ||
bufferindex++; | bufferindex++; | ||
- | } | + | |
- | else | + | |
- | { | + | |
if(!stage) | if(!stage) | ||
{ | { | ||
- | gps.latitude=(float)atoi(buffer); | + | gps.latitude=(float)atoi(buffer); |
+ | stage=TRUE; | ||
} | } | ||
- | if(stage==1) | + | else |
{ | { | ||
- | gps.latitude+=minutes*(float)atoi(buffer); | + | gps.latitude+=minutes*(float)atoi(buffer); |
} | } | ||
- | if(stage==2) | + | } |
- | { | + | break; |
- | gps.latitude+=0.01*minutes*(float)atoi(buffer); | + | case 4: |
- | } | + | |
- | memset(buffer,' | + | |
- | stage++; | + | gps.latitude=-gps.latitude; |
- | } | + | |
- | } | + | break; |
- | if(commacount==3 && | + | case 5: |
- | { | + | |
- | gps.latitude=-gps.latitude; | + | |
- | } | + | |
- | if(commacount==4) | + | |
- | { | + | |
- | if( (stage && | + | |
- | { | + | |
bufferindex++; | bufferindex++; | ||
- | } | + | |
- | else | + | |
- | { | + | |
if(!stage) | if(!stage) | ||
{ | { | ||
- | gps.longitude=(float)atoi(buffer); | + | gps.longitude=(float)atoi(buffer); |
- | } | + | stage=TRUE; |
- | if(stage==1) | + | |
- | { | + | |
- | gps.longitude+=minutes*(float)atoi(buffer); | + | |
- | } | + | |
- | if(stage==2) | + | |
- | { | + | |
- | gps.longitude+=0.01*minutes*(float)atoi(buffer); | + | |
- | } | + | |
- | memset(buffer,' | + | |
- | stage++; | + | |
- | } | + | |
- | } | + | |
- | if(commacount==5 && c==' | + | |
- | { | + | |
- | gps.longitude=-gps.longitude; | + | |
- | } | + | |
- | if(commacount==6) | + | |
- | { | + | |
- | gps.status=atoi(& | + | |
- | } | + | |
- | if(commacount==9) | + | |
- | { | + | |
- | if(stage) // | + | |
- | { | + | |
- | gps.altitude+=((float)atoi(& | + | |
- | memset(buffer,' | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | if(!pointcount) // | + | |
- | { | + | |
- | bufferindex++; | + | |
} | } | ||
else | else | ||
{ | { | ||
- | gps.altitude=(float)atoi(buffer); | + | gps.longitude+=minutes*(float)atoi(buffer); |
- | memset(buffer,' | + | |
- | stage++; | + | |
} | } | ||
- | } | + | } |
+ | break; | ||
+ | case 6: | ||
+ | if(c==' | ||
+ | { | ||
+ | gps.longitude=-gps.longitude; | ||
+ | } | ||
+ | break; | ||
+ | case 7: | ||
+ | gps.status=atoi(& | ||
+ | break; | ||
+ | case 10: | ||
+ | if(!pointcount) // | ||
+ | { | ||
+ | bufferindex++; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | gps.altitude=(float)atoi(buffer)*0.1; | ||
+ | | ||
} | } | ||
} | } | ||
else if(RMC) | else if(RMC) | ||
{ | { | ||
- | if(commacount==7) //speed in knots | + | if(commacount==8) //speed in knots |
{ | { | ||
- | if(stage) | + | if(!pointcount) |
{ | { | ||
- | gps.speed+=((float)atoi(& | + | bufferindex++; |
- | memset(buffer,' | + | |
} | } | ||
else | else | ||
{ | { | ||
- | if(!pointcount) | + | gps.speed=(float)atoi(buffer)*0.1; |
- | { | + | |
- | bufferindex++; | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | gps.speed=(float)atoi(buffer); | + | |
- | memset(buffer,' | + | |
- | stage++; | + | |
- | } | + | |
} | } | ||
} | } | ||
- | if(commacount==8) //the heading | + | if(commacount==9) //the heading |
{ | { | ||
- | if(stage) | + | |
+ | if(!pointcount) | ||
{ | { | ||
- | gps.heading+=((float)atoi(& | + | bufferindex++; |
- | memset(buffer,' | + | |
- | gps.packetflag=TRUE; //this is usually the last interesting part of the fix info to come through | + | |
} | } | ||
else | else | ||
{ | { | ||
- | if(!pointcount) | + | gps.heading=(float)atoi(buffer)*0.1; |
+ | toggle_pin; | ||
+ | if(!Gps.packetflag) //main has unlocked the data | ||
{ | { | ||
- | bufferindex++; | + | Gps.packetflag=TRUE; //this is usually the last interesting part of the fix info to come through |
- | } | + | Gps=gps; //copy into the global variable |
- | else | + | |
- | { | + | |
- | gps.heading=(float)atoi(buffer); | + | |
- | memset(buffer,' | + | |
- | stage++; | + | |
} | } | ||
} | } | ||
} | } | ||
} | } | ||
- | else | + | else if(!commacount) // |
{ | { | ||
- | if(commacount==0) //the header | + | if(bufferindex< |
{ | { | ||
- | if(bufferindex< | + | bufferindex++; |
+ | } | ||
+ | else | ||
+ | { | ||
+ | if(buffer==" | ||
{ | { | ||
- | bufferindex++; //increase the position in the buffer | + | GGA=TRUE; |
} | } | ||
- | else | + | if(buffer==" |
{ | { | ||
- | if(buffer==" | + | RMC=TRUE; |
- | { | + | |
- | GGA=TRUE; | + | |
- | } | + | |
- | if(buffer==" | + | |
- | { | + | |
- | RMC=TRUE; | + | |
- | } | + | |
- | memset(buffer,' | + | |
} | } | ||
} | } | ||
- | | + | } |
} | } | ||
- | }</ | + | } |
+ | </ |
code/interrupt_driven_nmea.1208027242.txt.gz · Last modified: 2008/07/19 23:31 (external edit)