65.9K
CodeProject 正在变化。 阅读更多。
Home

为您的桌面添加GPS支持

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (73投票s)

2003年1月4日

3分钟阅读

viewsIcon

459277

downloadIcon

9160

使用串行端口通过NMEA0183协议为您的台式计算机添加GPS(全球定位系统)支持。

Sample Image - GPS_support.jpg

引言

GPS 代表全球定位系统,是一种用于查找地理位置(即经度和纬度)有用信息的设备。但这些信息不限于经度和纬度。还可以从 GPS 获取其他信息,如时间、日期、指南针信息、速度等。

GPS 设备使用卫星(最少 3 颗,最多 14 颗)来查找你在地球上的位置。大多数现代 GPS 设备现在都支持一种称为 NMEA0183 的协议。该协议用于将地理位置信息从 GPS 传输到你的台式计算机或 PDA。

将 GPS 连接到你的电脑

要将数据从 GPS 传输到你的计算机,你需要一根可以连接到你的 GPS 的串口线。之后,你必须配置你的串口才能正确通信。在这个项目中,我将我的串口配置如下

COM Port: COM2
Baud Rate: 4800
Data Bits: 8
Parity: No Parity
Stop Bits: 2

你必须参考你的 GPS 手册来正确配置你的串口。

NMEA0183

正如我之前提到的,NMEA0183 是一个用于将位置信息从 GPS 传输到你的电脑的标准协议。我使用一个免费的库,它可以添加到你的项目中而无需任何修改。

你可以在上面的文件中找到这个库。感谢 Sam Blackburn 提供的优秀库。这个协议由几个句子组成,每个句子都以 $ 开头。例如,句子

"$GPGGA,104435.12,3337.19,N,11158.43,W,1,06,4.5,,,,,,"

包含以下信息(换句话说,翻译成)

Time: 10:44:35 AM UTC
Latitude: 33 37.19 North
Longitude: 111 58.43 West
Number of satellites: 6

使用库

首先,你必须将 nmea0183.lib 添加到你的项目中。为此,选择项目,设置,然后选择链接选项卡。在对象/库模块中,键入 nmea0183.lib 库的路径(例如:.\NMEA0183\Debug\NMEA0183.lib)。

然后按 OK 返回到项目。

如果你在你的项目中使用对话框,请将 "NMEA0183.h" 添加到你的对话框头文件中。在其他情况下,将 "NMEA0183.h" 添加到主头文件。
现在,添加一个名为 nmea0183 且变量类型为 NMEA0183 的成员变量,如下所示
NMEA0183 nmea0183;

之后,你必须为串口通信添加头文件和实现文件。 我使用来自 Shibu K.VCSerialCom。 在此 URL 查找他的文章:一个在 Win-9X/2000 中实现串口通信的简单类

添加一个名为 Serial 且变量类型为 CSerialCom 的成员变量,如下所示
CSerialCom Serial;

现在通过以下方式配置你的串口

//Open Port: COM2
Serial.OpenPort("COM2");

//Configure COM2
Serial.ConfigurePort(4800,          //Baud Rate
                     8,             //Data Bits
                     FALSE,         //Has Parity
                     NOPARITY,      //Parity Bits
                     TWOSTOPBITS    //Stop Bits
                    );

如果一切顺利,你可以通过 Read 成员函数从 GPS 获取信息,如下所示:注意:任何 NMEA0183 句子都将以 "\r\n" 字符结尾。
//Read data from GPS 
    
char Data[100]="\0";

BYTE DataByte='\0';
int nIndex=0;

//Obtaining information from GPS character by character
//Note: NMEA0183 sentences will finished by "\r\n" characters!
BOOL Return=Serial.ReadByte(DataByte);
while (DataByte!='\r' && DataByte!='\n' && Return==TRUE)
{
    Data[nIndex]=DataByte;
    nIndex++;
    Return=Serial.ReadByte(DataByte);
}
    
Data[nIndex++]='\r';
Data[nIndex++]='\n';
Data[nIndex++]='\0';

//Remove garbage characters if any exists!
nIndex=0;
while (Data[nIndex]!='$' && nIndex<100)
    nIndex++;

现在,是时候使用 nmea0183 成员变量了。 NMEA0183 类有两个非常重要的成员函数和一个成员变量

  1. AddTail() 用于添加从 GPS 检索的字符串。
  2. Parse() 用于解析检索到的字符串。 并且
  3. PlainText 一个成员变量,用于存储已翻译字符串的纯文本。

解决方案

我在我的基于对话框的项目中使用一个线程,它的职责是与 GPS 通信并在纯文本中显示位置信息。我的线程函数如下

UINT MyThread(LPVOID pParam)
{
    CSerialCom Serial;
    NMEA0183 nmea0183;
    CStringList StrList;

    if (!Serial.OpenPort("COM2"))
    {    
        AfxMessageBox("Can't Open Port!");
        return 0;
    }
    
    Serial.ConfigurePort(4800, 8, FALSE, NOPARITY, TWOSTOPBITS);
    
    //Read data from GPS
    char Data[100]="\0";
    
    BYTE DataByte='\0';
    int nIndex=0;
    
    BOOL Return=Serial.ReadByte(DataByte);
    while (DataByte!='\r' && DataByte!='\n' && Return==TRUE)
    {
        Data[nIndex]=DataByte;
        nIndex++;
        Return=Serial.ReadByte(DataByte);
    }
    
    Data[nIndex++]='\r';
    Data[nIndex++]='\n';
    Data[nIndex++]='\0';
    
    //Remove garbage characters
    nIndex=0;
    while (Data[nIndex]!='$' && nIndex<100)
        nIndex++;
    
    StrList.RemoveAll();
    StrList.AddTail(Data+nIndex);
    
    //Parse strings    
    POSITION position = StrList.GetHeadPosition();
    
    while(position!=NULL)
    {
        nmea0183 << StrList.GetNext(position);
        
        if (!nmea0183.Parse())
            AfxMessageBox("Can't parse!");
        else
        {    
            if (nmea0183.PlainText.GetLength()!= 0)
            {
                CString sMsg;
                sMsg.Format("%s",(const char *) nmea0183.PlainText);
                AfxMessageBox(sMsg);
            }
        }
    }
    Serial.ClosePort();
    
    return 0;
}

当你想显示 GPS 信息时,使用如下线程

AfxBeginThread(MyThread,NULL);

链接 NMEA0183 库

我们可以通过两种方式链接 NMEA0183 库:静态链接和动态链接。 对于这两种情况,你都必须为编译器选择合适的开关来编译 NMEA0183 库。 如果你想编译你的应用程序并将其与 MFC 静态链接,则应编译 NMEA0183 并静态链接。 如果你想编译你的应用程序并将其与 MFC 动态链接,则应动态编译 NMEA0183 库。

更多信息

有关 NMEA0183 协议和新规范的更多信息,请访问 NMEA.org

尽情享用!

© . All rights reserved.