liuweiele 发表于 2010-10-14 21:12:24

原创: 基于 ARM9 的 GPS测试软件

硬件平台: S3C2450 + 7寸TFT(800x480)
软件平台: X系统
开发环境: ADS1.2

liuweiele 发表于 2010-10-14 21:13:56

基于ADS的工程源码:
点击此处下载 ourdev_589841JVMZCT.rar(文件大小:132K) (原文件名:GPS_Test.rar)

liuweiele 发表于 2010-10-14 21:14:26

#include        "Include.h"

/*============================================================================*/

const        U32                __HeapSize                        =4096;
const        U32                __StackSize                        =2048;       
const        U32                __Priority                        =200;
const        char        __Name                        ="GPS测试软件";
const        U32                __Icon                                =0;
const        char        __IconPath                ="0.bmp";
const        char        __Version                ="V1.0";
const        char        __Date                        =__DATE__;
const        char        __Time                        =__TIME__;
const        char        __Desc                        ="Copyright:Liuwei";

HANDLE        hInst;

/*============================================================================*/

typedef        struct        PLANETINFO
{
        U8        ID;
        U8        RSS;
}PLANENTINFO;

/*============================================================================*/

HANDLE        hdev_com1;
char         buf;

char        gpgsv;        //GNSS 天空範圍內的衛星
char        gpgga;        //衛星定位定位資訊
char        gprmc;        //衛星定位定位資訊
char        gpvtg;        //對地方向及對地速度
char        gpmss;        //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;

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;
        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=dat;
                       
                        if((i>=127)||(dat=='\r')||(dat=='\n'))
                        {
                               
                               
                                buf='\0';
                                i=0;
                               
                                gps_rdy=1;
                               
                                if(buf=='$')
                                if(buf=='G')
                                if(buf=='P')
                                if(buf=='G')
                                if(buf=='S')
                                if(buf=='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,&v,&v,&v,&v,&v,&v,&v,&v,&v
                                                                        ,&v,&v,&v,&v,&v,&v,&v,&v,&v);

                                        if(v==1)
                                        {
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                               
                                        }                               
                                       
                                        if(v==2)
                                        {
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                       
                                        }                               
                                       
                                        if(v==3)
                                        {
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                               
                                                PlanetInfo.ID        =v;
                                                PlanetInfo.RSS        =v;
                                                                               
                                                InvalidateRect(hWndUI,0,0);
                                        }                               
                                       
                                       
                                }
                                ////
                               
                                if(buf=='$')
                                if(buf=='G')
                                if(buf=='P')
                                if(buf=='G')
                                if(buf=='G')
                                if(buf=='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=='$')
                                if(buf=='G')
                                if(buf=='P')
                                if(buf=='R')
                                if(buf=='M')
                                if(buf=='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=='$')
                                if(buf=='G')
                                if(buf=='P')
                                if(buf=='V')
                                if(buf=='T')
                                if(buf=='G')
                                {
                                        __strcpy(gpvtg,buf);
                                        InvalidateRect(hWndUI,0,0);
                                }
                                ////
                               
                                if(buf=='$')
                                if(buf=='G')
                                if(buf=='P')
                                if(buf=='M')
                                if(buf=='S')
                                if(buf=='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;
                                gpgsv        =0;
                                gprmc        =0;
                                gpgga        =0;
                                gpvtg        =0;
                                gpmss        =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;
                                                //&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;
                                               
                                                x=rc.dx-(12*20);
                                                y=5*20;
                                               
                                                for(i=0;i<12;i++)
                                                {
                                                       
                                                       
                                                        if(i<planet_num)
                                                        {
                                                                StrPrintf(buf,"%d",PlanetInfo.ID);
                                                                VProgressBar(hdc,x+i*20,y,16,80,RGB(200,0,0),GetWindowLong(hwnd,GWL_BKCOLOR),RGB(0,0,0),100,PlanetInfo.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
}

liuweiele 发表于 2010-10-14 21:17:44

软件实际运行效果(点击可放大图片):

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589842MGRB97.JPG
(原文件名:DSC_1224.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589843NK9YIB.JPG
(原文件名:DSC_1225.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589844GRMTD5.JPG
(原文件名:DSC_1228.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589845W197W0.JPG
(原文件名:DSC_1229.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589846JLTQAV.JPG
(原文件名:DSC_1254.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589847KJUT5L.JPG
(原文件名:DSC_1255.JPG)

liuweiele 发表于 2010-10-14 21:24:33

GPS模块图:
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589848SM2A81.JPG
(原文件名:DSC_1243.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589849T4OUPV.JPG
(原文件名:DSC_1247.JPG)

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589863XG5FD9.jpg
(原文件名:gps.jpg)

37772166 发表于 2010-10-14 21:26:02

占个沙发慢慢看。。

elecfun 发表于 2010-10-14 23:27:25

这屏不是一般的帅气啊

liuweiele 发表于 2010-10-15 08:59:03

GPS指令参考:
点击此处下载 ourdev_590005FBNFHU.pdf(文件大小:821K) (原文件名:NMEA-0183输出内容资料.pdf)

liuweiele 发表于 2010-10-15 09:38:02

这个GPS模块的信号很差,以上测试都是使用了2M的延长天线;如果使用自带的15CM天线,根本无法收到卫星信号.不知各位
是否也有这种情况?

jichidemayi 发表于 2010-10-16 10:14:56

不错
对字符串的比较换成strcmp的话更好,
这样就不要这么多if了

lirics 发表于 2010-10-17 11:00:23

mark

liuweiele 发表于 2010-10-18 14:27:57

回复【9楼】jichidemayi
不错
对字符串的比较换成strcmp的话更好,
这样就不要这么多if了
-----------------------------------------------------------------------

是的,看个人喜好.

goooogleman 发表于 2010-10-18 16:36:30

真不错。收藏了。

liuweiele 发表于 2010-10-18 17:44:50

回复【6楼】elecfun 熊
这屏不是一般的帅气啊
-----------------------------------------------------------------------

"私人专用屏",当然要做帅气一点~

itspy 发表于 2010-10-18 17:56:00

cool,这个用的什么系统啊,X系统是啥系统

liuweiele 发表于 2010-10-19 09:00:47

回复【14楼】itspy 独舞
cool,这个用的什么系统啊,x系统是啥系统
-----------------------------------------------------------------------

"X"是指未知的

kandy11 发表于 2011-3-13 01:48:00

mark
页: [1]
查看完整版本: 原创: 基于 ARM9 的 GPS测试软件