Bruceou 发表于 2024-3-3 10:22

【米尔-瑞萨RZ/G2UL开发板-试用评测】4G模组GPS使用

<div class='showpostmsg'><div><strong>。</strong></div>

<div>查看参考手册,移远带有GPS的芯片的USB Serial如下。</div>

<div></div>

<h1>1 应用简介</h1>

<div>1、若不使用 AT+QGPSCFG 指令对EC20进行配置,则会以默认参数开启GPS参数,NMEA端口开始上报,&quot;gpsnmeatype&quot;默认值为31,上报间隔为1s,每次上报所有种类的NMEA数据(GGA\RMC\GSV\GSA\VTG),若采用此默认配置,大多数使用者会觉得单次上报的数据太多且很多信息重复,建议大家使用QGPSCFG配置自己需要的NMEA数据格式,具体格式的差异可参考网上对NMEA数据的说明。</div>

<div>2、Linux环境下对NMEA数据的获取:</div>

<div>cat /dev/ttyUSB1 &amp; // NMEA数据从ttyUSB1输出</div>

<div>echo &quot;AT+QGPS=1&quot; &gt; /dev/ttyUSB2 // 开启GPS会话</div>

<div>可观察到ttyUSB1输出NMEA数据,如下:</div>

<div></div>

<div>3、程序设计过程中,若有固定频率更新位置需求,可考虑采用读取NMEA端口数据的形式,并将其配置适合自己需求的NMEA格式和数据更新间隔。若产品执行获取位置指令的频率较低且间隔时间不固定,也可考虑直接在AT指令端口使用AT+QGPSLOC指令进行实时位置信息的获取。</div>

<div></div>

<div></div>

<h1>2 GPS数据解析</h1>

<div>NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association )为海用电子设备制定的标准格式。目前业已成了GPS导航设备统一的RTCM(Radio Technical Commission for Maritime services)标准协议。</div>

<div>GPS接收机上电后,会自动通过串口或USB口发送NMEA0183格式的数据包,它是一组包含有各种地理位置信息的字符串,字符串格式为:</div>

<div>$信息类型,xxx,xxx,xxx,xxx,xxx,xxx,xxx,</div>

<div>每行开头的字符都是&lsquo;$&rsquo;,接着是信息类型,后面是数据,以逗号分隔开。一行完整的数据如下:</div>

<div>$GPRMC,063102.00,A,2932.293196,N,10636.147385,E,0.0,45.5,250818,2.3,W,A*10</div>

<div>信息类型为:</div>

<div>GPVTG:地面速度信息</div>

<div>GPRMC:推荐最小定位信息</div>

<div>GPGSA:当前卫星信息</div>

<div>GPGGA:GPS定位信息</div>

<div>GPGSV:可见卫星信息</div>

<div>这里我们只解析GPRMC和GPGGA的信息。</div>

<h2>2.1 GPRMC数据详解</h2>

<div>$GPRMC,&lt;1&gt;,&lt;2&gt;,&lt;3&gt;,&lt;4&gt;,&lt;5&gt;,&lt;6&gt;,&lt;7&gt;,&lt;8&gt;,&lt;9&gt;,&lt;10&gt;,&lt;11&gt;,&lt;12&gt;*hh</div>

<div>&lt;1&gt; UTC时间,hhmmss(时分秒)格式</div>

<div>&lt;2&gt; 定位状态,A=有效定位,V=无效定位</div>

<div>&lt;3&gt; 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)</div>

<div>&lt;4&gt; 纬度半球N(北半球)或S(南半球)</div>

<div>&lt;5&gt; 经度dddmm.mmmm(度分)格式(前面的0也将被传输)</div>

<div>&lt;6&gt; 经度半球E(东经)或W(西经)</div>

<div>&lt;7&gt; 地面速率(000.0~999.9节,前面的0也将被传输)</div>

<div>&lt;8&gt; 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)</div>

<div>&lt;9&gt; UTC日期,ddmmyy(日月年)格式</div>

<div>&lt;10&gt; 磁偏角(000.0~180.0度,前面的0也将被传输)</div>

<div>&lt;11&gt; 磁偏角方向,E(东)或W(西)</div>

<div>&lt;12&gt; 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)</div>

<div>解析内容:</div>

<div>1.时间,这个是格林威治时间,是世界时间(UTC),我们需要把它转换成北京时间(BTC),BTC和UTC差了8个小时,要在这个时间基础上加8个小时。</div>

<div>2.定位状态,在接收到有效数据前,这个位是&lsquo;V&rsquo;,后面的数据都为空,接到有效数据后,这个位是&lsquo;A&rsquo;,后面才开始有数据。</div>

<div>3.纬度,我们需要把它转换成度分秒的格式,计算方法:</div>

<div>如接收到的纬度是:4546.40891</div>

<div>4546.40891 / 100 = 45.4640891 可以直接读出45度</div>

<div>4546.40891&ndash;45 * 100 = 46.40891 可以直接读出46分</div>

<div>46.40891&ndash;46 = 0.40891 * 60 = 24.5346 读出24秒</div>

<div>所以纬度是:45度46分24秒。</div>

<div>4.南北纬,这个位有两种值&lsquo;N&rsquo;(北纬)和&lsquo;S&rsquo;(南纬)</div>

<div>5.经度的计算方法和纬度的计算方法一样</div>

<div>6.东西经,这个位有两种值&lsquo;E&rsquo;(东经)和&lsquo;W&rsquo;(西经)</div>

<div>7.速率,这个速率值是 海里/时,单位是节,要把它转换成千米/时,根据:1海里 = 1.85公里,把得到的速率乘以1.85。</div>

<div>8.航向,指的是偏离正北的角度</div>

<div>9.日期,这个日期是准确的,如:200818表示2018年08月20日,这个日期是准确的,不需要转换。</div>

<h2>2.2 GPGGA数据详解</h2>

<div>$GPGGA,&lt;1&gt;,&lt;2&gt;,&lt;3&gt;,&lt;4&gt;,&lt;5&gt;,&lt;6&gt;,&lt;7&gt;,&lt;8&gt;,&lt;9&gt;,M,&lt;10&gt;,M,&lt;11&gt;,&lt;12&gt;*xx</div>

<div>$GPGGA:起始引导符及语句格式说明(本句为GPS定位数据);</div>

<div>&lt;1&gt; UTC时间,格式为hhmmss.sss;</div>

<div>&lt;2&gt; 纬度,格式为ddmm.mmmm(第一位是零也将传送);</div>

<div>&lt;3&gt; 纬度半球,N或S(北纬或南纬)</div>

<div>&lt;4&gt; 经度,格式为dddmm.mmmm(第一位零也将传送);</div>

<div>&lt;5&gt; 经度半球,E或W(东经或西经)</div>

<div>&lt;6&gt; 定位质量指示,0=定位无效,1=定位有效;</div>

<div>&lt;7&gt; 使用卫星数量,从00到12(第一个零也将传送)</div>

<div>&lt;8&gt; 水平精确度,0.5到99.9</div>

<div>&lt;9&gt; 天线离海平面的高度,-9999.9到9999.9米 M 指单位米</div>

<div>&lt;10&gt; 大地水准面高度,-9999.9到9999.9米 M 指单位米</div>

<div>&lt;11&gt; 差分GPS数据期限(RTCM SC-104),最后设立RTCM传送的秒数量</div>

<div>&lt;12&gt; 差分参考基站标号,从0000到1023(首位0也将传送)。</div>

<h1>3 GPS编程</h1>

<div>GPS解析主要有两个部分,一个是USB转串口的配置,另外一个就是GPS的解析。下面就一一介绍。</div>

<div><strong>1.</strong><strong>串口配置</strong></div>

<div>由于我是通过串口来进行数据传输,也就是把GPS定位的信息,通过串口最后输出到我们的终端设备上。</div>

<div>/**</div>

<div>* @brief 串口设置函数</div>

<div>* @param fd</div>

<div>baud_rate</div>

<div>data_bits</div>

<div>parity</div>

<div>stop_bits</div>

<div>* @retval int</div>

<div>*/</div>

<div>int set_GPS_com_config(int fd,int baud_rate,int data_bits, char parity, int stop_bits)</div>

<div>{</div>

<div>struct termios new_cfg;</div>

<div>int speed;</div>

<div>/* 保存并测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息 */</div>

<div>if (tcgetattr(fd, &amp;new_cfg) != 0)</div>

<div>{</div>

<div>perror(&quot;tcgetattr save&quot;);</div>

<div>return -1;</div>

<div>}</div>

<div>//修改控制模式,保证程序不会占用串口</div>

<div>new_cfg.c_cflag |= CLOCAL;</div>

<div>//修改控制模式,使得能够从串口中读取输入数据</div>

<div>new_cfg.c_cflag |= CREAD;</div>

<div>new_cfg.c_oflag &amp;= ~(ONLCR | OCRNL);</div>

<div>new_cfg.c_iflag &amp;= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);</div>

<div>new_cfg.c_iflag &amp;= ~(ICRNL | INLCR);</div>

<div>new_cfg.c_iflag &amp;= ~(IXON | IXOFF | IXANY);</div>

<div>/* 设置波特率 */</div>

<div>switch (baud_rate)</div>

<div>{</div>

<div>case 2400:</div>

<div>{</div>

<div>speed = B2400;</div>

<div>}</div>

<div>break;</div>

<div>case 4800:</div>

<div>{</div>

<div>speed = B4800;</div>

<div>}</div>

<div>break;</div>

<div>case 9600:</div>

<div>{</div>

<div>speed = B9600;</div>

<div>}</div>

<div>break;</div>

<div>case 19200:</div>

<div>{</div>

<div>speed = B19200;</div>

<div>}</div>

<div>break;</div>

<div>case 38400:</div>

<div>{</div>

<div>speed = B38400;</div>

<div>}</div>

<div>break;</div>

<div>default:</div>

<div>case 115200:</div>

<div>{</div>

<div>speed = B115200;</div>

<div>}</div>

<div>break;</div>

<div>}</div>

<div>cfsetispeed(&amp;new_cfg, speed);//输入波特率</div>

<div>cfsetospeed(&amp;new_cfg, speed);//输出波特率</div>

<div>switch (data_bits) /* 设置数据位 */</div>

<div>{</div>

<div>case 7:</div>

<div>{</div>

<div>new_cfg.c_cflag |= CS7;</div>

<div>}</div>

<div>break;</div>

<div>default:</div>

<div>case 8:</div>

<div>{</div>

<div>new_cfg.c_cflag |= CS8;</div>

<div>}</div>

<div>break;</div>

<div>}</div>

<div>switch (parity) /* 设置奇偶校验位 */</div>

<div>{</div>

<div>default:</div>

<div>case &#39;n&#39;:</div>

<div>case &#39;N&#39;:</div>

<div>{</div>

<div>new_cfg.c_cflag &amp;= ~PARENB;</div>

<div>new_cfg.c_iflag &amp;= ~INPCK;</div>

<div>}</div>

<div>break;</div>

<div>case &#39;o&#39;:</div>

<div>case &#39;O&#39;:</div>

<div>{</div>

<div>new_cfg.c_cflag |= (PARODD | PARENB);</div>

<div>new_cfg.c_iflag |= INPCK;</div>

<div>}</div>

<div>break;</div>

<div>case &#39;e&#39;:</div>

<div>case &#39;E&#39;:</div>

<div>{</div>

<div>new_cfg.c_cflag |= PARENB;</div>

<div>new_cfg.c_cflag &amp;= ~PARODD;</div>

<div>new_cfg.c_iflag |= INPCK;</div>

<div>}</div>

<div>break;</div>

<div>case &#39;s&#39;: /* as no parity */</div>

<div>case &#39;S&#39;:</div>

<div>{</div>

<div>new_cfg.c_cflag &amp;= ~PARENB;</div>

<div>new_cfg.c_cflag &amp;= ~CSTOPB;</div>

<div>}</div>

<div>break;</div>

<div>}</div>

<div>switch (stop_bits) /* 设置停止位 */</div>

<div>{</div>

<div>default:</div>

<div>case 1:</div>

<div>{</div>

<div>new_cfg.c_cflag &amp;= ~CSTOPB;</div>

<div>}</div>

<div>break;</div>

<div>case 2:</div>

<div>{</div>

<div>new_cfg.c_cflag |= CSTOPB;</div>

<div>}</div>

<div>}</div>

<div>//修改输出模式,原始数据输出</div>

<div>new_cfg.c_oflag &amp;= ~OPOST;</div>

<div>new_cfg.c_lflag &amp;= ~(ICANON | ECHO | ECHOE | ISIG);//我加的</div>

<div>new_cfg.c_lflag &amp;= ~(ISIG | ICANON);</div>

<div>//设置等待时间和最小接收字符</div>

<div>new_cfg.c_cc = 0; /* 读取一个字符等待0*(0/10)s */</div>

<div>new_cfg.c_cc = 1; /* 读取字符的最少个数为0 */</div>

<div>//如果发生数据溢出,接收数据,但是不再读取 刷新收到的数据但是不读</div>

<div>tcflush(fd, TCIFLUSH); /* 处理未接收字符 */</div>

<div>if ((tcsetattr(fd, TCSANOW, &amp;new_cfg)) != 0) /* 激活新配置 */</div>

<div>{</div>

<div>perror(&quot;tcsetattr action&quot;);</div>

<div>return -1;</div>

<div>}</div>

<div>//printf(&quot;serial set success\n&quot;);</div>

<div>return 0;</div>

<div>}</div>

<div>/**</div>

<div>* @brief 打开串口函数</div>

<div>* @param com</div>

<div>* @retval int</div>

<div>*/</div>

<div>int open_GPS_port(const char *com_port)</div>

<div>{</div>

<div>int fd;</div>

<div>/*分别为com1,com2, com3对应 ttyS0 ttyS1 ttyS2 */</div>

<div>fd = open( com_port, O_RDWR|O_NOCTTY|O_NDELAY);</div>

<div>if (fd &lt; 0)</div>

<div>{</div>

<div>perror(&quot;Can&#39;t Open Serial Port&quot;);</div>

<div>return -1;</div>

<div>}</div>

<div>/*恢复串口为阻塞状态*/</div>

<div>if (fcntl(fd,F_SETFL,0)&lt;0)</div>

<div>{</div>

<div>perror(&quot;fcntl F_SETFL\n&quot;);</div>

<div>}</div>

<div>/*测试是否为终端设备*/</div>

<div>if(isatty(STDIN_FILENO) == 0)</div>

<div>{</div>

<div>perror(&quot;standard input is not a terminal device&quot;);</div>

<div>}</div>

<div>return fd;</div>

<div>}</div>

<div>/**</div>

<div>* @brief 串口初始化函数</div>

<div>* @param com_port</div>

<div>* @retval int</div>

<div>*/</div>

<div>int init_GPS_port(const char *com_port)</div>

<div>{</div>

<div>int fd;</div>

<div>if ((fd = open_GPS_port(com_port)) &lt; 0 )</div>

<div>{</div>

<div>perror(&quot;open_port&quot;);</div>

<div>return -1;</div>

<div>}</div>

<div>if(set_GPS_com_config(fd,9600,8,&#39;N&#39;,1) &lt; 0)</div>

<div>{</div>

<div>perror(&quot;set_com_config&quot;);</div>

<div>return -1;</div>

<div>}</div>

<div>return fd;</div>

<div>}</div>

<div><strong>2.GPS</strong><strong>数据分析</strong></div>

<div>char *buff = NULL;</div>

<div>GPRMC_t gprmc;</div>

<div>GPGGA_t gpgga;</div>

<div>/**</div>

<div>* @brief GPS解析函数</div>

<div>* @param AT_fd:串口文件描述符</div>

<div>* @ DATA_fd:串口文件描述符</div>

<div>* @retval Nono</div>

<div>*/</div>

<div>void GPS_Analysis(int AT_fd,int DATA_fd)</div>

<div>{</div>

<div>int nread,nwrite;</div>

<div>char send_buff;</div>

<div>char recv_buff;</div>

<div>char *ptr = NULL;</div>

<div>char AT_Buff;</div>

<div>int ret = 0;</div>

<div>#if 0</div>

<div>uint32_t time =0;</div>

<div>uint32_t lat =0 ;</div>

<div>uint32_t lon =0;</div>

<div>uint32_t speed =0;</div>

<div>uint32_t head =0;</div>

<div>uint32_t alt =0;</div>

<div>#endif</div>

<div>while(1)</div>

<div>{</div>

<div>memset(AT_Buff,0,sizeof(AT_Buff));</div>

<div>strcpy(AT_Buff, &quot;AT+QGPS=1&quot;);</div>

<div>GPS_Set(AT_fd , AT_Buff);</div>

<div>if(buff != NULL)</div>

<div>{</div>

<div>break;</div>

<div>}</div>

<div>memset(AT_Buff,0,sizeof(AT_Buff));</div>

<div>strcpy(AT_Buff, &quot;AT+QGPSEND&quot;);</div>

<div>GPS_Set(AT_fd , AT_Buff);</div>

<div>sleep(1);</div>

<div>}</div>

<div>//接收数据</div>

<div>while(1)</div>

<div>{</div>

<div>memset(&amp;gprmc, 0, sizeof(gprmc));</div>

<div>memset(&amp;gpgga, 0, sizeof(gpgga));</div>

<div>memset(recv_buff,0,sizeof(recv_buff));</div>

<div>nread = read(DATA_fd,recv_buff,sizeof(recv_buff));</div>

<div>#ifdef DEBUG_GPS</div>

<div>printf(&quot;nread=%d,%s\n&quot;,nread,recv_buff);</div>

<div>printf(&quot;=================2===================\n&quot;);</div>

<div>#endif</div>

<div>//strcpy(buff, recv_buff);</div>

<div>//保存数据</div>

<div>ptr = strstr(recv_buff, &quot;$GPRMC&quot;);</div>

<div>ret = sscanf(ptr, &quot;$GPRMC,%f,%c,%f,%*c,%f,%*c,%f,%f,%d,%f,%*c,%*c*&quot;,</div>

<div>&amp;gprmc.time,&amp;gprmc.state, &amp;gprmc.lat, &amp;gprmc.lon,</div>

<div>&amp;gprmc.speed, &amp;gprmc.head, &amp;gprmc.date,&amp;gprmc.dec);</div>

<div>ptr = strstr(recv_buff, &quot;$GPGGA&quot;);</div>

<div>ret = sscanf(ptr, &quot;$GPGGA,%f,%f,N,%f,E,%d,%d,%f,%f,M,%f,M,,*&quot;,</div>

<div>&amp;gpgga.time, &amp;gpgga.lat, &amp;gpgga.lon,</div>

<div>&amp;gpgga.state, &amp;gpgga.num, &amp;gpgga.hdop, &amp;gpgga.alt, &amp;gpgga.geoid);</div>

<div>#if 0</div>

<div>time = (int)(gprmc.time*100) % 100 + ((int)gprmc.time % 100) * 100 +\</div>

<div>((int)gprmc.time%10000/100) *60 * 100 + ((int)gprmc.time/10000)* 3600 * 100;</div>

<div>lat = ((int)(gprmc.lat/100) + (gprmc.lat-(int)gprmc.lat/100*100)/60)*10000000;</div>

<div>lon = ((int)(gprmc.lon/100) + (gprmc.lon-(int)gprmc.lon/100*100)/60)*10000000;</div>

<div>speed = gprmc.speed* 1.852;</div>

<div>head = gprmc.head;</div>

<div>alt = gpgga.alt;</div>

<div>#endif</div>

<div>//打印数据</div>

<div>print_GPS_RMC(&amp;gprmc);</div>

<div>print_GPS_GGA(&amp;gpgga);</div>

<div>}</div>

<div>}</div>

<div>/**</div>

<div>* @brief GPS打开函数</div>

<div>* @param AT_fd:串口文件描述符</div>

<div>* @ AT :AT指令</div>

<div>* @retval Nono</div>

<div>*/</div>

<div>void GPS_Set(int AT_fd,char *AT)</div>

<div>{</div>

<div>int nread,nwrite;</div>

<div>char send_buff;</div>

<div>char recv_buff;</div>

<div>memset(send_buff,0,sizeof(send_buff));</div>

<div>strcpy(send_buff, AT);</div>

<div>strcat(send_buff,&quot;\r&quot;);</div>

<div>nwrite = write(AT_fd,send_buff,strlen(send_buff));</div>

<div>#ifdef DEBUG_GPS</div>

<div>printf(&quot;nwrite=%d,%s\n&quot;,nwrite,send_buff);</div>

<div>#endif</div>

<div>//waiting for AT&#39;s ACK等待回应</div>

<div>memset(recv_buff,0,sizeof(recv_buff));</div>

<div>nread = read(AT_fd,recv_buff,sizeof(recv_buff));</div>

<div>buff = strstr(recv_buff,&quot;OK&quot;);</div>

<div>//memset(buff,0,strlen(buff));</div>

<div>#ifdef DEBUG_GPS</div>

<div>printf(&quot;nread=%d,%s\n&quot;,nread,recv_buff);</div>

<div>printf(&quot;================1======================\n&quot;);</div>

<div>#endif</div>

<div>}</div>

<div>/**</div>

<div>* @brief GPS-RMC信息打印</div>

<div>* @param gprmc_data:</div>

<div>* @retval Nono</div>

<div>*/</div>

<div>void print_GPS_RMC(GPRMC_t *gprmc_data)</div>

<div>{</div>

<div>printf(&quot; \n&quot;);</div>

<div>printf(&quot;===========================================================\n&quot;);</div>

<div>printf(&quot;== 全球GPS定位导航模块 ==\n&quot;);</div>

<div>printf(&quot;================RMC信息====================================\n&quot;);</div>

<div>printf(&quot;===========================================================\n&quot;);</div>

<div>printf(&quot;== GPS state bit : %c \n&quot;,gprmc_data-&gt;state);</div>

<div>printf(&quot;== Date : 20%02d-%02d-%02d \n&quot;,gprmc_data-&gt;date%100,(gprmc_data-&gt;date%10000)/100,gprmc_data-&gt;date/10000);</div>

<div>printf(&quot;== 纬度 : 北纬:%d度%d分%d秒 \n&quot;,((int)gprmc_data-&gt;lat) / 100, (int)(gprmc_data-&gt;lat - ((int)gprmc_data-&gt;lat / 100 * 100)), (int)(((gprmc_data-&gt;lat - ((int)gprmc_data-&gt;lat / 100 * 100)) - ((int)gprmc_data-&gt;lat - ((int)gprmc_data-&gt;lat / 100 * 100))) * 60.0));</div>

<div>printf(&quot;== 经度 : 东经:%d度%d分%d秒 \n&quot;,((int)gprmc_data-&gt;lon) / 100, (int)(gprmc_data-&gt;lon - ((int)gprmc_data-&gt;lon / 100 * 100)), (int)(((gprmc_data-&gt;lon - ((int)gprmc_data-&gt;lon / 100 * 100)) - ((int)gprmc_data-&gt;lon - ((int)gprmc_data-&gt;lon / 100 * 100))) * 60.0));</div>

<div>printf(&quot;== 速度 : %.3f m/s \n&quot;,gprmc_data-&gt;speed * 1.852);</div>

<div>printf(&quot;== 航向 : %.3f 度 \n&quot;,gprmc_data-&gt;head );</div>

<div>printf(&quot;===========================================================\n&quot;);</div>

<div>}</div>

<div>/**</div>

<div>* @brief GPS-GGA信息打印</div>

<div>* @param gpgga_data:</div>

<div>* @retval Nono</div>

<div>*/</div>

<div>void print_GPS_GGA(GPGGA_t *gpgga_data)</div>

<div>{</div>

<div>printf(&quot; \n&quot;);</div>

<div>printf(&quot;===========================================================\n&quot;);</div>

<div>printf(&quot;== 全球GPS定位导航模块 ==\n&quot;);</div>

<div>printf(&quot;================GGA信息====================================\n&quot;);</div>

<div>printf(&quot;===========================================================\n&quot;);</div>

<div>printf(&quot;== 纬度 : 北纬:%d度%d分%d秒 \n&quot;,((int)gpgga_data-&gt;lat) / 100, (int)(gpgga_data-&gt;lat - ((int)gpgga_data-&gt;lat / 100 * 100)), (int)(((gpgga_data-&gt;lat - ((int)gpgga_data-&gt;lat / 100 * 100)) - ((int)gpgga_data-&gt;lat - ((int)gpgga_data-&gt;lat / 100 * 100))) * 60.0));</div>

<div>printf(&quot;== 经度 : 东经:%d度%d分%d秒 \n&quot;,((int)gpgga_data-&gt;lon) / 100, (int)(gpgga_data-&gt;lon - ((int)gpgga_data-&gt;lon / 100 * 100)), (int)(((gpgga_data-&gt;lon - ((int)gpgga_data-&gt;lon / 100 * 100)) - ((int)gpgga_data-&gt;lon - ((int)gpgga_data-&gt;lon / 100 * 100))) * 60.0));</div>

<div>printf(&quot;== 数量 : %d 颗 \n&quot;,gpgga_data-&gt;num);</div>

<div>printf(&quot;== 精度 : %.3f \n&quot;,gpgga_data-&gt;hdop);</div>

<div>printf(&quot;== 海拔 : %.3f m \n&quot;,gpgga_data-&gt;alt);</div>

<div>printf(&quot;===========================================================\n&quot;);</div>

<div>}</div>

<div>【注意】</div>

<ol>
        <li>由于我直接获取的是格林威治时间即世界时间(UTC),所以要把它转换成北京时间(BTC),也就是在这个时间基础上加8个小时。</li>
        <li>经纬度,GPRMC返回的纬度数据位ddmm.mmmm格式即度分格式,我们把它转换成常见的度分秒的格式,计算方法:如接收到的纬度是:3029.60430<br />
        3029.60430/100=30.2960430可以直接读出30度, 3029.60430&ndash;30*100=29.60430, 可以直接读出29分 (29.60430&ndash;29)*60 =0.60430*60=36.258读出36秒, 所以纬度是:30度29分36秒。</li>
        <li>GPRMC返回的速率值是海里/时,单位是节,把它转换成千米/时,换算为:1海里=1.85公里,把得到的速率乘以1.85。</li>
        <li>航向指的是偏离正北的角度。</li>
        <li>GPRMC的日期格式为:ddmmyy,如:200818表示2018年08月20日,这个日期是准确的,不需要转换。</li>
</ol>

<div><strong>3.</strong><strong>主函数打开串口</strong><strong>设备读</strong><strong>操作</strong></div>

<div>#define DEBUG_GPS</div>

<div>int GPS_DATA_fd = -1; //GPS_DATA描述符</div>

<div>int GPS_AT_fd = -1; //GPS_AT描述符;</div>

<div>/**</div>

<div>* @brief main函数</div>

<div>* @param Nono</div>

<div>* @retval Nono</div>

<div>*/</div>

<div>int main(int argc, char **argv)</div>

<div>{</div>

<div>GPS_AT_fd = init_GPS_port(DEVICE_AT_GPS); //初始化AT GPS</div>

<div>if(GPS_AT_fd &lt; 0)</div>

<div>{</div>

<div>printf(&quot;open GPS_AT_port failed!\n&quot;);</div>

<div>}</div>

<div>else</div>

<div>{</div>

<div>printf(&quot;open GPS_AT_port success!\n&quot;);</div>

<div>}</div>

<div>GPS_DATA_fd = init_GPS_port(DEVICE_DATA_GPS); //初始化DATA GPS</div>

<div>if(GPS_AT_fd &lt; 0)</div>

<div>{</div>

<div>printf(&quot;open GPS_DATA_port failed!\n&quot;);</div>

<div>}</div>

<div>else</div>

<div>{</div>

<div>printf(&quot;init GPS_port success!\n&quot;);</div>

<div>GPS_Analysis(GPS_AT_fd,GPS_DATA_fd);</div>

<div>}</div>

<div>return 0;</div>

<div>}</div>

<div>【注】EC20的USB转串口信息在本文前已经给出,需要使用两个设备,ttyUSB1和ttyUSB2,ttyUSB1是GPS输出信息,ttyUSB2是AT命令配置设备,因此需要打开两个设备。</div>

<div><strong>4.</strong><strong>测试</strong></div>

<div>编译完成后,执行程序,会有下面的主要信息,可以看到GPS的解析数据。</div>

<div></div>

<div></div>

<div>&nbsp;</div>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页: [1]
查看完整版本: 【米尔-瑞萨RZ/G2UL开发板-试用评测】4G模组GPS使用