你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32F303开发】+如何解析GPS数据  

[复制链接]
caizhiwei 提问时间:2015-7-27 09:09 /
本帖最后由 caizhiwei 于 2015-7-27 09:16 编辑

实现步骤如下:
1.初始化usart3:
  1. #define UART3_TX_BUF_SIZE        1*128
  2. #define UART3_RX_BUF_SIZE        512
复制代码
  1. unsigned char Uart1TxBuf[UART1_TX_BUF_SIZE]={0};                /* com1_rf发送缓冲区 */
  2. unsigned char Uart1RxBuf[UART1_RX_BUF_SIZE]={0};                /* com1_rf接收缓冲区 */

  3. unsigned char Uart3TxBuf[UART3_TX_BUF_SIZE]={0};                /* com3_发送缓冲区 */
  4. unsigned char Uart3RxBuf[UART3_RX_BUF_SIZE]={0};                /* com3_接收缓冲区 */

  5. bool Uart1RxBuf_full =false;
  6. bool Uart3RxBuf_full =false;
复制代码

  1. void USART3_Init(u32 Baudrate)
  2. {

  3.   USART_InitTypeDef  USART_InitStructure;
  4.   GPIO_InitTypeDef   GPIO_InitStructure;
  5.   
  6.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
  7.   
  8.   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
  9.   
  10.   //这里USART3映射到PC10和PC11是部分映射,没有映射时时端口是PB10和PB11,
  11.   //完全映射时(GPIO_FullRemap_USART3)是PD8和PD9 (但是64引脚没有引出PD8和PD9)
  12.   GPIO_PinRemapConfig(GPIO_PartialRemap_USART3,ENABLE);// I/O口重映射开启.
  13.      
  14.   /*Remap Pc10 USART3.TX推挽输出*/
  15.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  16.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  18.   GPIO_Init(GPIOC, &GPIO_InitStructure);
  19.   
  20.   /*remap Pc11 USART3.RX浮空输入 */
  21.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  22.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        
  23.   GPIO_Init(GPIOC, &GPIO_InitStructure);

  24.   USART_InitStructure.USART_BaudRate = Baudrate;
  25.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  26.   USART_InitStructure.USART_StopBits = USART_StopBits_1;
  27.   USART_InitStructure.USART_Parity = USART_Parity_No;
  28.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  29.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  30.   USART_Init(USART3, &USART_InitStructure);
  31.   
  32.   USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//接收中断使能
  33.   USART_Cmd(USART3, ENABLE);

  34. }
复制代码
2.写带fifo缓冲区的串口中断:
  1. void  USART3_IRQHandler(void)
  2. {
  3.     static u16 RxCount;
  4.      
  5.   if(USART_GetFlagStatus(USART3,USART_IT_RXNE)==SET)
  6.   {   
  7.     USART_ClearITPendingBit(USART3,USART_IT_RXNE);//清除中断标志

  8.         
  9.      Uart3RxBuf[RxCount] = USART_ReceiveData(USART3);         

  10.        RxCount++; // must not change it !
  11.            
  12.       if (RxCount >= UART3_RX_BUF_SIZE) //  
  13.        {     
  14.          RxCount=0;
  15.          Uart3RxBuf_full = true;
  16.        }           
  17.   }
  18. }
复制代码
3.从缓冲区中提取有效数据:
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: gps_pro
  4. *        功能说明:  从串口缓冲区中解析出GPS数据包。插入到主程序中执行即可。分析结果存放在全局变量 myGPS
  5. *        形    参:  无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */

  9. void gps_pro(void)
  10. {
  11.     uint16_t i=0;
  12.        
  13.     char *p,*pt;  

  14.                 if (Uart3RxBuf_full)
  15.                    {  

  16.                     USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //禁止接收中断
  17.                    
  18.                     Uart3RxBuf_full = false;
  19.                    
  20.                 //LCD_print_0816Num(3, 5,  1 ,0);//debug

  21.                     p = (char *)Uart3RxBuf;
  22.                     pt = strchr(p, '
  23. 4. 解析语义:
  24. [code]void GPS_Data_update()
  25. {
  26.    
  27.     char * start_p = GpsBuf;      

  28.     char *pos_p;
  29.    /*
  30.    int strncmp(const char *string1, const char *string2, size_t count);
  31.    比较字符串string1和string2大小,只比较前面count个字符. 比较过程中,
  32.    任何一个字符串的长度小于count, 则count将被较短的字符串的长度取代.
  33.    此时如果两串前面的字符都相等, 则较短的串要小.
  34.    返回值< 0, 表示string1的子串小于string2的子串;
  35.    返回值为0, 表示string1的子串等于string2的子串;
  36.    返回值> 0, 表示string1的子串大于string2的子串.
  37.    */
  38.   if(strncmp(GpsBuf, "$GPGGA",6)==0)
  39.   {
  40.    //ShowStringPos (0, 4,"$GPGGA"); //bebug
  41.    
  42.         /*字段1 :UTC 时间,hhmmss.sss,时分秒格式 */
  43.         pos_p = strchr(start_p, ','); //查找字符串s中首次出现字符c的位置,剥离c前面的信息
  44.         if (pos_p == 0)
  45.         {
  46.             return;//2个逗号连在一起的情况
  47.         }
  48.     pos_p++;  // p+1后指向UTC时间
  49.     myGPS.Hour = StrToIntFix(pos_p, 2);
  50.         pos_p += 2;
  51.         myGPS.Min = StrToIntFix(pos_p, 2);
  52.         pos_p += 2;
  53.         myGPS.Sec = StrToIntFix(pos_p, 2);
  54.          //微秒忽略
  55.         
  56.      /* 字段2 :纬度ddmm.mmmm,度分格式(前导位数不足则补0)*/
  57.      pos_p = strchr(pos_p, ','); //接着刚才指针位置找下一个逗号
  58.         if (pos_p == 0)
  59.         {
  60.            return;
  61.         }
  62.         pos_p++;
  63.         
  64.         myGPS.WeiDu_Du = StrToIntFix(pos_p, 2);
  65.         pos_p += 2;
  66.         myGPS.WeiDu_Fen = StrToIntFix(pos_p, 2) * 10000;
  67.         pos_p += 3;
  68.         myGPS.WeiDu_Fen += StrToIntFix(pos_p, 4);
  69.             
  70.         /* 字段3 :N(北纬)或S(南纬) */
  71.         pos_p = strchr(pos_p, ',');
  72.         if (pos_p == 0)
  73.         {
  74.                 return;
  75.         }
  76.         pos_p++;
  77.         if (*pos_p == 'S')
  78.         {
  79.                 myGPS.NS = 'S';
  80.         }
  81.         else if (*pos_p == 'N')
  82.         {
  83.                 myGPS.NS = 'N';
  84.         }
  85.         else
  86.         {
  87.                 return;
  88.         }
  89.         
  90.     /* 字段4 :经度dddmm.mmmm,度分格式(前导位数不足则补0) */
  91.         pos_p = strchr(pos_p, ',');
  92.         if (pos_p == 0)
  93.         {
  94.                 return;
  95.         }
  96.         pos_p++;
  97.         myGPS.JingDu_Du = StrToIntFix(pos_p, 3);
  98.         pos_p += 3;
  99.         myGPS.JingDu_Fen = StrToIntFix(pos_p, 2) * 10000;
  100.         pos_p += 3;
  101.         myGPS.JingDu_Fen += StrToIntFix(pos_p, 4);
  102.        
  103.         /* 字段5 :E(东经)或W(西经) */
  104.         pos_p = strchr(pos_p, ',');
  105.         if (pos_p == 0)
  106.         {
  107.                 return;
  108.         }
  109.         pos_p++;
  110.         if (*pos_p == 'E')
  111.         {
  112.                 myGPS.EW = 'E';
  113.         }
  114.         else if (*pos_p == 'W')
  115.         {
  116.                 myGPS.EW = 'W';
  117.         }
  118.         
  119.         /* 字段6 :GPS状态,0=未定位,1=非差分定位,2=差分定位,3=无效PPS,6=正在估算 */
  120.         pos_p = strchr(pos_p, ',');
  121.         if (pos_p == 0)
  122.         {
  123.                 return;
  124.         }
  125.         pos_p++;
  126.         if ((*pos_p == '1') || (*pos_p == '2'))
  127.         {
  128.                 myGPS.PositionOk = 1;
  129.         }
  130.         else
  131.         {
  132.                 myGPS.PositionOk = 0;
  133.         }

  134.        
  135.           /* 字段7:正在使用的卫星数量(00 - 12)(前导位数不足则补0) */
  136.                 pos_p = strchr(pos_p, ',');
  137.                 if (pos_p == 0)
  138.                 {
  139.                         return;
  140.                 }
  141.                 pos_p++;
  142.                 myGPS.ViewNumber = StrToInt(pos_p);
  143.                
  144.                 //p += 2;
  145.        
  146.                 /* 字段8:HDOP水平精度因子(0.5 - 99.9) */
  147.                 pos_p = strchr(pos_p, ',');
  148.                 if (pos_p == 0)
  149.                 {
  150.                         return;
  151.                 }
  152.                 pos_p++;
  153.                 myGPS.HDOP = StrToInt(pos_p);
  154.        
  155.                 /* 字段9:海拔高度(-9999.9 - 99999.9) */
  156.                 pos_p= strchr(pos_p, ',');
  157.                 if (pos_p == 0)
  158.                 {
  159.                         return;
  160.                 }
  161.                 pos_p++;
  162.                 myGPS.Altitude = StrToInt(pos_p);
  163.         //后面的,39.5,M,-15.5,M,6.8,0000*68 丢弃
  164.         
  165.    
  166.   }
  167.   
  168.   //if(strncmp(GpsBuf, "$GPRMC",6)==0)
  169.   //{
  170.    //ShowStringPos (0, 4,"$GPRMC"); //bebug
  171.   //}
  172.   
  173. }
复制代码

5.运行:
在RTOS中用一个或两个任务执行   gps_pro(); GPS_Data_update();
在main函数中用while(1){gps_pro(); GPS_Data_update();}
QQ截图20150508161840.jpg

BSP.zip (10.35 KB, 下载次数: 338)

评分

参与人数 2 ST金币 +31 收起 理由
shanqs + 1 很给力!
沐紫 + 30 赞一个!

查看全部评分

收藏 4 评论26 发布时间:2015-7-27 09:09

举报

26个回答
caizhiwei 回答时间:2015-7-27 09:29:49
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: DispGPSStatus
  4. *        功能说明: 打印GPS数据包解码结果
  5. *        形    参:无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void DispGPSStatus(void)
  10. {
  11.         char buf[128];

  12.         /* 纬度 */
  13.         if (myGPS.NS == 'S')
  14.         {
  15.                 sprintf(buf, "南纬 %02d.%06d°", myGPS.WeiDu_Du, gps_FenToDu(myGPS.WeiDu_Fen));

  16.                 sprintf(&buf[strlen(buf)], "=%02d°%02d'%02d"", myGPS.WeiDu_Du,
  17.                         myGPS.WeiDu_Fen / 10000, gps_FenToMiao(myGPS.WeiDu_Fen));
  18.        
  19.         }
  20.         else
  21.         {
  22.                 sprintf(buf, "北纬 %02d.%06d°",myGPS.WeiDu_Du, gps_FenToDu(myGPS.WeiDu_Fen));

  23.                 sprintf(&buf[strlen(buf)], "=%02d°%02d'%02d"", myGPS.WeiDu_Du,
  24.                         myGPS.WeiDu_Fen / 10000, gps_FenToMiao(myGPS.WeiDu_Fen));
  25.         }
  26.         printf(buf);
  27.        

  28.         /* 经度 */
  29.         if (myGPS.EW == 'E')
  30.         {
  31.                 sprintf(buf, "  东经 %03d.%06d°", myGPS.JingDu_Du, gps_FenToDu(myGPS.JingDu_Fen));

  32.                 sprintf(&buf[strlen(buf)], "=%03d°%02d'%02d"", myGPS.JingDu_Du,
  33.                         myGPS.WeiDu_Fen / 10000, gps_FenToMiao(myGPS.JingDu_Fen));
  34.         }
  35.         else
  36.         {
  37.                 sprintf(buf, "  西经 =%03d.%06d°", myGPS.JingDu_Du, gps_FenToDu(myGPS.JingDu_Fen));

  38.                 sprintf(&buf[strlen(buf)], "=%03d°%02d'%02d"", myGPS.JingDu_Du,
  39.                         myGPS.JingDu_Fen / 10000, gps_FenToMiao(myGPS.JingDu_Fen));
  40.         }
  41.         printf(buf);

  42.         /* 速度 */
  43.         sprintf(buf, "  速度 = %5d.%d KM/h", myGPS.SpeedKM / 10, myGPS.SpeedKM % 10);
  44.         printf(buf);

  45.         /* 海拔 */
  46.         sprintf(buf, "  海拔 = %5d.%d M", myGPS.Altitude / 10, myGPS.Altitude % 10);
  47.         printf(buf);
  48.        
  49.         printf("\n\r正在使用的卫星数量%d.", myGPS.ViewNumber);
  50.        
  51.         if(myGPS.PositionOk == 1)
  52.            printf("\n\rGPS定位成功!");

  53.         printf("\r");        /* 回车,不换行 */
  54. }
复制代码
沐紫 回答时间:2015-7-27 09:43:12
  1.     <Code Language="csharp">
  2.             <![CDATA[private $type$ $field$;

  3.     public $type$ $property$
  4.     {
  5.         get { return $field$;}
  6.         set
  7.         {
  8.             $field$ = value;
  9.             this.RaisePropertyChanged("$property$");
  10.         }
  11.     }
  12.     $end$]]>
  13.             </Code>
复制代码

哎呦不错哦0118 回答时间:2017-5-1 19:42:31
您好,我最近也在做这个实验,用您的这个代码试了一下(按照我自己的需求改了一点),但是出来的结果不对,您能帮我分析一下吗PS:实验数据如图

图

图
caizhiwei 回答时间:2015-7-27 09:18:30
编辑贴子的时候代码总是错位,试了好几次,编辑之后好好的,点了发帖之后就乱了。。。
沐紫 回答时间:2015-7-27 09:45:11
先谢谢楼主~

上面是我试的代码,感觉挺好用……
caizhiwei 回答时间:2015-7-27 09:54:37
谢啦,不过有需要的可以下载源码看看,都在里面的
Paderboy 回答时间:2015-7-27 10:01:20
多谢分享。。。学习了
逆风的沙 回答时间:2015-7-27 10:05:25
好东西 多谢楼主了,
JackieLaura 回答时间:2015-7-27 11:36:43
上位机结合百度地图,就是个导航系统了。。
moyanming2013 回答时间:2015-7-27 11:40:48
1.jpg
哈哈2 回答时间:2015-7-27 13:39:49
呵呵呵 ,可以参考一下
加拿大 回答时间:2015-7-27 13:45:26
,不错
caizhiwei 回答时间:2015-11-18 15:39:15
突然发现我这个程序有bug,经纬度的秒转化为分的时候没有考虑到进位!
yizhidaguiw 回答时间:2016-1-24 13:46:10
源码缺少一个头文件?
yizhidaguiw 回答时间:2016-1-24 13:46:56
求楼主QQ什么的联系方式  
12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版