源码:
#include "Include.h"
/*============================================================================*/
const U32 __HeapSize =4096;
const U32 __StackSize =2048;
const U32 __Priority =200;
const char __Name[32] ="GPS测试软件";
const U32 __Icon =0;
const char __IconPath[32] ="0.bmp";
const char __Version[8] ="V1.0";
const char __Date[16] =__DATE__;
const char __Time[16] =__TIME__;
const char __Desc[32] ="Copyright:Liuwei";
HANDLE hInst;
/*============================================================================*/
typedef struct PLANETINFO
{
U8 ID;
U8 RSS;
}PLANENTINFO;
/*============================================================================*/
HANDLE hdev_com1;
char buf[128];
char gpgsv[128]; //GNSS 天空範圍內的衛星
char gpgga[128]; //衛星定位定位資訊
char gprmc[128]; //衛星定位定位資訊
char gpvtg[128]; //對地方向及對地速度
char gpmss[128]; //MSK 接收訊號
float time,longitude,latitude,speed,way;
U32 date;
U32 state,NS,WE;
U32 code;
U32 planet_num; //可用卫星数
float precision; //精度
float height; //海拔高度
float ave_height; //平均高度
U32 unit0;
U32 unit1;
HWND hWndUI;
HANDLE hThread;
int rx_exit=0;
PLANENTINFO PlanetInfo[12];
static int gps_rdy=0;
/*============================================================================*/
static int __strcpy(char *dst,char *src)
{
while(1)
{
*dst++=*src;
if(*src=='\0') break;
src++;
}
}
/*============================================================================*/
/*============================================================================*/
/*
nmea数据如下:
$GPGGA,121252.000,3937.3032,N,11611.6046,E,1,05,2.0,45.9,M,-5.7,M,,0000*77
$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54
$GPVTG,359.95,T,,M,15.15,N,28.0,K,A*04
$GPGGA,121253.000,3937.3090,N,11611.6057,E,1,06,1.2,44.6,M,-5.7,M,,0000*72
$GPGSA,A,3,14,15,05,22,18,26,,,,,,,2.1,1.2,1.7*3D
$GPGSV,3,1,10,18,84,067,23,09,67,067,27,22,49,312,28,15,47,231,30*70
$GPGSV,3,2,10,21,32,199,23,14,25,272,24,05,21,140,32,26,14,070,20*7E
$GPGSV,3,3,10,29,07,074,,30,07,163,28*7D
说明:NMEA0183格式以“$”开始,主要语句有GPGGA,GPVTG,GPRMC等
1、 GPS DOP and Active Satellites(GSA)当前卫星信息
$GPGSA,<1>,<2>,<3>,<3>,,,,,<3>,<3>,<3>,<4>,<5>,<6>,<7><CR><LF>
$GPGSA,A,3,16,23,31,32,14,,,,,,,,1.53,1.20,0.95*0A
<1>模式 :M = 手动, A = 自动。
<2>定位型式 1 = 未定位, 2 = 二维定位, 3 = 三维定位。
<3>PRN 数字:01 至 32 表天空使用中的卫星编号,最多可接收12颗卫星信息。
<4> PDOP位置精度因子(0.5~99.9)
<5> HDOP水平精度因子(0.5~99.9)
<6> VDOP垂直精度因子(0.5~99.9)
<7> Checksum.(检查位).
2、 GPS Satellites in View(GSV)可见卫星信息
$GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,?<4>,<5>,<6>,<7>,<8><CR><LF>
$GPGSV,3,2,12,42,39,118,,32,38,225,20,20,34,252,,31,34,060,34*76
<1> GSV语句的总数
<2> 本句GSV的编号
<3> 可见卫星的总数,00 至 12。
<4> 卫星编号, 01 至 32。
<5>卫星仰角, 00 至 90 度。
<6>卫星方位角, 000 至 359 度。实际值。
<7>讯号噪声比(C/No), 00 至 99 dB;无表未接收到讯号。
<8>Checksum.(检查位).
第<4>,<5>,<6>,<7>项个别卫星会重复出现,每行最多有四颗卫星。其余卫星信息会于次一行出现,若未使用,这些字段会空白。
3、Global Positioning System Fix Data(GGA)GPS定位信息
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh<CR><LF>
$GPGGA,050458.000,2459.8991,N,10242.8698,E,1,5,1.20,1885.0,M,-32.2,M,,*45
<1> UTC时间,hhmmss(时分秒)格式
<2> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<3> 纬度半球N(北半球)或S(南半球)
<4> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<5> 经度半球E(东经)或W(西经)
<6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
<7> 正在使用解算位置的卫星数量(00~12)(前面的0也将被传输)
<8> HDOP水平精度因子(0.5~99.9)
<9> 海拔高度(-9999.9~99999.9)
<10> 地球椭球面相对大地水准面的高度
<11> 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
<12> 差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)
4、Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐定位信息
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
$GPRMC,050459.000,A,2459.8990,N,10242.8698,E,0.67,158.73,190808,,,A*6A
<1> UTC时间,hhmmss(时分秒)格式
<2> 定位状态,A=有效定位,V=无效定位
<3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<4> 纬度半球N(北半球)或S(南半球)
<5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<6> 经度半球E(东经)或W(西经)
<7> 地面速率(000.0~999.9节,前面的0也将被传输)
<8> 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
<9> UTC日期,ddmmyy(日月年)格式
<10> 磁偏角(000.0~180.0度,前面的0也将被传输)
<11> 磁偏角方向,E(东)或W(西)
<12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
5、 Track Made Good and Ground Speed(VTG)地面速度信息
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh<CR><LF>
<1> 以真北为参考基准的地面航向(000~359度,前面的0也将被传输)
<2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输)
<3> 地面速率(000.0~999.9节,前面的0也将被传输)
<4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输)
<5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
*/
void gps_rx_thread(void *p)
{
char dat;
int i;
DCB dcb;
U32 v[20];
U32 event;
////
if(DeviceIoCtrl(hdev_com1,CMD_COM_GET_DCB,0,&dcb))
{
dcb.BaudRate=9600;
DeviceIoCtrl(hdev_com1,CMD_COM_SET_DCB,0,&dcb);
}
i=0;
while(rx_exit==0)
{
event=DeviceWaitEvent(hdev_com1,0);
if(event==EVT_COM_RXCHAR)
{
DeviceRead(hdev_com1,0,&dat,1);
buf[i++]=dat;
if((i>=127)||(dat=='\r')||(dat=='\n'))
{
buf[i]='\0';
i=0;
gps_rdy=1;
if(buf[0]=='$')
if(buf[1]=='G')
if(buf[2]=='P')
if(buf[3]=='G')
if(buf[4]=='S')
if(buf[5]=='V')
{
__strcpy(gpgsv,buf);
StrScanf(gpgsv, "$GPGSV,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d"
,&v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7],&v[8],&v[9]
,&v[10],&v[11],&v[12],&v[13],&v[14],&v[15],&v[16],&v[17],&v[18]);
if(v[1]==1)
{
PlanetInfo[0].ID =v[3];
PlanetInfo[0].RSS =v[6];
PlanetInfo[1].ID =v[7];
PlanetInfo[1].RSS =v[10];
PlanetInfo[2].ID =v[11];
PlanetInfo[2].RSS =v[14];
PlanetInfo[3].ID =v[15];
PlanetInfo[3].RSS =v[18];
}
if(v[1]==2)
{
PlanetInfo[4].ID =v[3];
PlanetInfo[4].RSS =v[6];
PlanetInfo[5].ID =v[7];
PlanetInfo[5].RSS =v[10];
PlanetInfo[6].ID =v[11];
PlanetInfo[6].RSS =v[14];
PlanetInfo[7].ID =v[15];
PlanetInfo[7].RSS =v[18];
}
if(v[1]==3)
{
PlanetInfo[8].ID =v[3];
PlanetInfo[8].RSS =v[6];
PlanetInfo[9].ID =v[7];
PlanetInfo[9].RSS =v[10];
PlanetInfo[10].ID =v[11];
PlanetInfo[10].RSS =v[14];
PlanetInfo[11].ID =v[15];
PlanetInfo[11].RSS =v[18];
InvalidateRect(hWndUI,0,0);
}
}
////
if(buf[0]=='$')
if(buf[1]=='G')
if(buf[2]=='P')
if(buf[3]=='G')
if(buf[4]=='G')
if(buf[5]=='A')
{
__strcpy(gpgga,buf);
//$GPGGA,121253.000,3937.3090,N,11611.6057,E,1,06,1.2,44.6,M,-5.7,M,,0000*72
StrScanf(gpgga,"$GPGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c",
&time,&latitude,&NS,&longitude,&WE,&code,&planet_num,&precision,&height,&unit0,&ave_height,&unit1);
InvalidateRect(hWndUI,0,0);
}
////
if(buf[0]=='$')
if(buf[1]=='G')
if(buf[2]=='P')
if(buf[3]=='R')
if(buf[4]=='M')
if(buf[5]=='C')
{
__strcpy(gprmc,buf);
//$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54
StrScanf(gprmc,"$GPRMC,%f,%c,%f,%c,%f,%c,%f,%f,%d",
&time,&state,&latitude,&NS,&longitude,&WE,&speed,&way,&date);
InvalidateRect(hWndUI,0,0);
}
////
if(buf[0]=='$')
if(buf[1]=='G')
if(buf[2]=='P')
if(buf[3]=='V')
if(buf[4]=='T')
if(buf[5]=='G')
{
__strcpy(gpvtg,buf);
InvalidateRect(hWndUI,0,0);
}
////
if(buf[0]=='$')
if(buf[1]=='G')
if(buf[2]=='P')
if(buf[3]=='M')
if(buf[4]=='S')
if(buf[5]=='S')
{
__strcpy(gpmss,buf);
InvalidateRect(hWndUI,0,0);
}
////
}
}
}
ExitThread(0);
}
/*============================================================================*/
static RESULT WinProc(HWND hwnd,U32 msg,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
RECT rc;
int x,y,i;
switch(msg)
{
case WM_CREATE:
buf[0] =0;
gpgsv[0] =0;
gprmc[0] =0;
gpgga[0] =0;
gpvtg[0] =0;
gpmss[0] =0;
rx_exit =0;
gps_rdy =0;
break;
////////
case WM_TIMER:
// SendMessage(hwnd,WM_CLOSE,0,0);
break;
////////
case WM_PAINT:
hdc=BeginPaint(hwnd);
if(hdc&& (gps_rdy==1))
{
GetClientRect(hwnd,&rc);
ClrScreen(hdc,GetWindowLong(hwnd,GWL_BKCOLOR));
////
x=2;
y=2;
Label(hdc,x,y,rc.dx-4,20,RGB(200,0,0),GetWindowBkColor(hwnd),RGB(0,0,0),LEFT,gpgsv);
y+=19;
////
Label(hdc,x,y,rc.dx-4,20,RGB(200,0,0),GetWindowBkColor(hwnd),RGB(0,0,0),LEFT,gprmc);
y+=19;
////
Label(hdc,x,y,rc.dx-4,20,RGB(200,0,0),GetWindowBkColor(hwnd),RGB(0,0,0),LEFT,gpgga);
y+=19;
////
Label(hdc,x,y,rc.dx-4,20,RGB(200,0,0),GetWindowBkColor(hwnd),RGB(0,0,0),LEFT,gpvtg);
y+=19;
////
if(1);
{
char buf[64];
//&time,&state,&latitude,&NS,&longitude,&WE,&speed,&way,&date;
StrPrintf(buf,"坐标: %.4f%c,%.4f%c ",latitude/100,NS,longitude/100,WE);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
StrPrintf(buf,"速度: %.2f ",speed);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
StrPrintf(buf,"方向: %.2f ",way);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
StrPrintf(buf,"卫星数: %d ",planet_num);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
StrPrintf(buf,"水平精度: %.2fM ",precision);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
StrPrintf(buf,"海拔高度: %.2f%c ",height,unit0);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
StrPrintf(buf,"平均高度: %.2f%c ",ave_height,unit1);
DrawText(hdc,x,y,rc.dx-4,20,RGB(0,0,100),GetWindowBkColor(hwnd),LEFT,buf);
y+=16;
////
}
if(1)
{
char buf[8];
x=rc.dx-(12*20);
y=5*20;
for(i=0;i<12;i++)
{
if(i<planet_num)
{
StrPrintf(buf,"%d",PlanetInfo[i].ID);
VProgressBar(hdc,x+i*20,y,16,80,RGB(200,0,0),GetWindowLong(hwnd,GWL_BKCOLOR),RGB(0,0,0),100,PlanetInfo[i].RSS);
DrawText(hdc,x+i*20,y,16,80,RGB(240,240,240),RGB_TRANS,CENTER,buf);
}
else
{
VProgressBar(hdc,x+i*20,y,16,80,RGB(200,0,0),GetWindowLong(hwnd,GWL_BKCOLOR),RGB(0,0,0),100,0);
}
}
y+=80;
DrawText(hdc,x,y,rc.dx-x,20,RGB(0,0,128),RGB_TRANS,CENTER,"GPS卫星信号强度");
}
}
EndPaint(hwnd,hdc);
break;
////////
case WM_CLOSE:
if(MessageBox(hwnd,"确定要退出程序吗?","信息",MB_YESNO|MB_ICONQUESTION)==IDYES)
{
if(hdev_com1)
{
//it=1;
TerminateThread(hThread,0);
DeviceClose(hdev_com1,0);
}
DestroyWindow(hwnd);
}
break;
////////
case WM_DESTROY:
PostQuitMessage(hwnd);
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
}
//__KERNEL_H__
/*============================================================================*/
/*============================================================================*/
int WinMain(HANDLE hInstance,void *argv)
{
HWND hwnd;
MSG msg;
WNDCLASS wcls;
////
hInst =hInstance;
wcls.lpClassName =(char*)__Name;
wcls.Style =0;
wcls.lpfnProc =WinProc;
wcls.hIcon =0;
wcls.hIconSm =0;
wcls.hCursor =0;
wcls.BkColor =RGB(160,160,160);
hwnd =CreateWindow( &wcls,(char*)__Name,WS_OVERLAPPEDWINDOW,
20,30,480,240,
NULL,NULL,hInst,NULL);
hWndUI =hwnd;
ShowWindow(hwnd,SW_SHOW);
hdev_com1 =DeviceOpen("COM1",0);
if(hdev_com1)
{
hThread=CreateThread(gps_rx_thread,0,8192,10,0);
}
else
{
MessageBox(hwnd,"打开串口失败!","错误",MB_OK|MB_ICONERROR);
SendMessage(hwnd,WM_CLOSE,0,0);
}
while(GetMessage(&msg,hwnd))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.lParam
} |