如何截取GPS接收机的GPGGA通信协议数据
定义OnComm函数如下,接收字符数据即开始执行,判断为哪什么数据,若是GPGGA的信息将会显示在接收文本框中。
界面图片
- /*------------------------------------------------------
- * OnComm函数实现
- * 触发条件:当输入缓冲区有字符时,有消息触发
- * 执行结果:字符接收,并显示在文本框m_strEditReceiveMsg
- *------------------------------------------------------*/
- #define CR 0x0D //定义回车
- #define LF 0x0A //定义换行
- LONG CReadGPSView::OnComm(WPARAM ch, LPARAM port)
- {
- /*------------------------------------------------------
- * 声明变量:静态变量连续接收字符并保存
- * 普通变量
- *------------------------------------------------------*/
- static char checkSum = 0;//异或交验
- static int count = 0;
- static unsigned char buf[20];
- static char chigh,clow;//用于交验,计算半
- static int flag = -1;//用于标记“接收阶段”
- /*------------------------------------------------------
- * 判断接受信息(只接收GPGGA信息)
- * $GPGGA,135105.000,3605.1204,N,12022.0206,E,1,03,8.5,
- * 53.0,M,-3.2,M,,0000*7B
- *------------------------------------------------------*/
- switch(ch)
- {
- //包首
- case '$':
- checkSum = 0;//开始计算checksum交验值
- flag = 0;
- m_strPortRxData.Empty();
- m_strPortRxData += ch;//接受字符
- break;
- //包尾
- case '*':
- if ( flag ==5 )
- {
- flag = 16;
- m_strPortRxData += ch;//接受字符
- clow = checkSum & 0x0F;//接收交验码低四位
- chigh = ( checkSum >> 4 ) & 0x0F;//接收交验码高四位
- //计算校验码转化后的字符。
- if ( clow < 10 )
- clow = '0' + clow;
- else
- clow = 'A' + ( clow - 10 );
- if ( chigh < 10 )
- chigh = '0' + chigh;
- else
- chigh = 'A' + ( chigh - 10 );
- }
- break;
- //包名"GPGGA"检测,连续接受GPGGA后,flag值为5;
- case 'G':
- if (flag == 0)//标志 上一次接受字符为 '$',(这是第一个'G'字符)
- {
- flag = 1;
- m_strPortRxData += ch;//接受字符
- }
- else
- {
- if (flag == 2)//标志 上一次接受字符为 'P',(这是第二个'G'字符)
- {
- flag = 3;
- m_strPortRxData += ch;//接受字符
- }
- else
- {
- if ( flag == 3)//标志 上一次接受字符为第二个 'G',(这是第三个'G'字符)
- {
- flag = 4;
- m_strPortRxData += ch;//接受字符
- }
- else
- flag = -1;
- }
- }
- break;
- case 'P':
- if (flag == 1)//标志 上一次接受字符为第一个 'G',(这是'P'字符)
- {
- flag = 2;
- m_strPortRxData += ch;//接受字符
- }
- else
- flag = -1;
- break;
- case 'A':
- if (flag == 4)//标志 上一次接受字符为第三个 'G',(这是'A'字符)
- {
- flag = 5;
- m_strPortRxData += ch;//接受字符
- }
- else
- flag = -1;
- break;
- case CR:
- break;
- case LF:
- m_strPortRxData.Empty();
- break;
- /*----------------------------------------------------
- * Default 部分功能:
- * 1.接收校验字符(接受到*后,falg=16)
- * 2.接收校验后(flag=15),判断校验字符是否正确
- * 3.接收普通字符(接受GPGGA包头名称后)
- * 4.接收
- * 算法:
- *----------------------------------------------------*/
- default:
- //处理接收校验码
- if ( flag == 16 )//标志 已经接收到 GPGGA 协议包尾'*'
- {
- flag--;
- m_strPortRxCheck += ch;
- m_strPortRxData += ch;
- }
- else
- //以下程序段在接收,判断校验码是否正确
- if ( flag == 15 )//标志 已经接收到 GPGGA 协议包校验码
- {
- CString check="";
- check.Format("%c%c",chigh,clow);
- /*
- if ( check != m_strPortRxCheck )//校验错
- {
- AfxMessageBox("校验错");
- }
- else//校验正确,1.显示数据; 2.数据截取处理。
- {
- */
- /*----------------------------------------------------
- * 显示接受的字符
- *----------------------------------------------------*/
- m_strPortRxData += ch;
- m_strPortRxData += CR;
- m_strPortRxData += LF;
- CString strTemp;
- strTemp = m_strPortRxData.Mid(7,6);
- char *temp = (char*) ((LPCTSTR)strTemp);
- char tbuf[10];
- tbuf[0]=temp[0];
- tbuf[1]=temp[1];
- tbuf[2]=':';
- tbuf[3]=temp[2];
- tbuf[4]=temp[3];
- tbuf[5]=':';
- tbuf[6]=temp[4];
- tbuf[7]=temp[5];
- tbuf[8]=0;
- m_Time = tbuf;
- strTemp = m_strPortRxData.Mid(18,27);
- temp = (char*) ((LPCTSTR)strTemp);
- tbuf[0]=temp[0];
- tbuf[1]=temp[1];
- tbuf[2]='^';
- tbuf[3]=temp[2];
- tbuf[4]=temp[3];
- tbuf[5]='-';
- tbuf[6]=temp[4];
- tbuf[7]=temp[5];
- tbuf[8]='"';
- tbuf[9]=0;
- /*----------------------------------------------------
- * 数据存储
- *---------------------------------------------------*/
- if (!m_pSet->IsEOF())
- m_pSet->MoveLast();
- m_pSet->AddNew();
- UpdateData(FALSE);
- m_pSet->m_WDZ = atof(strTemp);
- UpdateData(FALSE);
- if( m_pSet->CanUpdate())
- {
- if(!m_pSet->Update())
- AfxMessageBox(_T("添加记录失败!"));
- else
- AfxMessageBox(_T("成功添加一条记录!"));
- }
- else
- {
- AfxMessageBox(_T("不能添加记录!"));
- }
- m_strEditRX = m_strPortRxData;//接收字符
- UpdateData(FALSE); //将接收到的字符显示在接收编辑框中
- return 0;
- ;
- //}
- }
- else
- {
- if ( flag == 5 )//标志 已经接收到 GPGGA 协议包头名称'GPGGA'
- {
- m_strPortRxData += ch;//接受字符
- checkSum ^= ch;//计算交验值
- //if ( )
- }
- else
- break;
- }
- break;
- }
- return 0;
- }