NMEA((National Marine Electronics Association)0183 ASCII 的格式
本人將使用收到的 RMC 資料串進行解析,取出衛星當下的時間
Message Structure:
$GPRMC,hhmmss,status,latitude,N,longitude,E,spd,cog,ddmmyy,mv,mvE,mode*cs<CR><LF>
Example:
$GPRMC,083559.00,A,4717.11437,N,00833.91522,E,0.004,77.52,091202,,,A*57
Field No. | Example | Format | Name | Unit | Description |
0 | $GPRMC | string | $GPRMC | - | Message ID, RMC protocol header |
1 | 083559.00 | hhmmss.sss | hhmmss. | - | UTC Time, Time of position fix |
2 | A | character | Status | - | Status,
V = Navigation receiver warning, A = Data valid, see Position Fix Flags description |
3 | 4717.11437 | ddmm.mmmm | Latitude | - | Latitude, Degrees + minutes, see Format description |
4 | N | character | N | - | N/S Indicator, hemisphere N=north or S=south |
5 | 00833.91522 | dddmm. Mmmm |
Longitude | - | Longitude, Degrees + minutes, see Format description |
6 | E | character | E | - | E/W indicator, E=east or W=west |
7 | 0.004 | numeric | Spd | knots | Speed over ground |
8 | 77.52 | numeric | Cog | degrees | Course over ground |
9 | 091202 | ddmmyy | date | - | Date in day, month, year format |
10 | - | numeric | mv | degrees | Magnetic variation value, not being output by receiver |
11 | - | character | mvE | - | Magnetic variation E/W indicator, not being output by receiver |
12 | - | character | mode | - | Mode Indicator, see Position Fix Flags description |
13 | *57 | hexadecimal | cs | - | Checksum |
14 | - | character | <CR><LF> | - | Carriage Return and Line Feed |
程式撰寫
- 使用編譯器: CCS PCWHD
- 使用單晶片:Microchip PIC18F45K22
透過剛剛介紹的$GPSRMC 接收來自衛星訊號的ASCII內容,裡面包含了有UTC標準時間,本文透過解析內容並轉為資料串再回傳給單晶片修正RTC時間
副程式除了解析出時間外,同時也將轉換經緯度座標位置
char *srg: 傳入接收來自於RS232資料串
TDateTime *DT: 傳入欲擺放時間日期等資訊的結構串
TCoordinate *Coordinate:傳入欲擺放經緯度等資訊的結構串
程序完成後成功傳為0
int GPS_GPRMC_stream_decoder(char *srg, TDateTime *DT, TCoordinate *Coordinate)
{
char st = 0, ed = 0, index = 0;
//step1: find $GPRMC position,not found reutn value = -1
if (strFind(srg, (char*)"$GPRMC", 0) == -1)
return -1;
//step2: find first ',' position in string
st = charFind(srg, ',', 0);
if (st == -1)
return -1;
char str[16];
char str_length = strlen(srg);
while (st != -1 && index < str_length)
{
ed = charFind(srg, ',', st+1);
switch (++index)
{
case 1 : DT->hour = atoi(StrmnCpy(str, srg, st+1, 2));
DT->min = atoi(StrmnCpy(str, srg, st+3, 2));
DT->sec = atoi(StrmnCpy(str, srg, st+5, 2));
break;
case 2 : if (*StrmnCpy(str, srg, st+1, 1) != 'A')
return -1;
break;
case 3 : StrmnCpy(str, srg, st+1, ed-st-1);
Coordinate->Latitude = GPS_StrtoLatitude(&str, ed-st-1);
break;
case 4 : StrmnCpy(str, srg, st+1, 1);
Coordinate->N_S = str[0];
break;
case 5 : StrmnCpy(str, srg, st+1, ed-st-1);
Coordinate->Longitude = GPS_StrtoLongitude(&str, ed-st-1);
break;
case 6 : StrmnCpy(str, srg, st+1, 1);
Coordinate->E_W = str[0];
break;
case 7 : StrmnCpy(str, srg, st+1, ed-st-1);
Coordinate->speed = strtof(str, '0');
break;
case 9 : DT->m_day = atoi(StrmnCpy(str, srg, st+1, 2));
DT->month = atoi(StrmnCpy(str, srg, st+3, 2));
DT->year = atoi(StrmnCpy(str, srg, st+5, 2));
DT->w_day = RTC_Weekend_Transfer(20, DT->year, DT->month, DT->m_day);
break;
}
st = ed;
}
return 0;
}
尋找字串中指定的字串內容處在位置
int strFind(char *srg, char *s, size_t st)
{
BYTE pos;
for (pos=st, srg+=st; *srg != '\0'; srg++, pos++)
if (strspn(srg, s) == strlen(s))
return pos;
return -1;
}
尋找字元中指定的字串內容處在位置
int charFind(char *s, char c, size_t st)
{
BYTE pos;
for (pos=st, s+=st; *s != '\0'; s++, pos++)
if (*s == c)
return pos;
return -1;
}
複製字串
char *StrmnCpy(char *str, char *srg, size_t m, size_t n)
{
int i=0;
char *s;
for(s=str, i=m, srg+=m; i<m+n; i++)
*s++ = *srg++;
*s++ = '\0';
return str;
}
沒有留言:
張貼留言
留言板