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

查看: 9588|回复: 25

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

  [复制链接]

43

主题

292

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-28
发表于 2015-7-27 09:09:50 | 显示全部楼层 |阅读模式
本帖最后由 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, 下载次数: 325)

评分

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

查看全部评分

<
回复

使用道具 举报

43

主题

292

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-28
 楼主| 发表于 2015-7-27 09:18:30 | 显示全部楼层
编辑贴子的时候代码总是错位,试了好几次,编辑之后好好的,点了发帖之后就乱了。。。
回复 支持 反对

使用道具 举报

43

主题

292

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-28
 楼主| 发表于 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. }
复制代码
回复 支持 反对

使用道具 举报

307

主题

3125

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-7-17
发表于 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>
复制代码

回复 支持 反对

使用道具 举报

307

主题

3125

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-7-17
发表于 2015-7-27 09:45:11 | 显示全部楼层
先谢谢楼主~

上面是我试的代码,感觉挺好用……
回复 支持 反对

使用道具 举报

43

主题

292

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-28
 楼主| 发表于 2015-7-27 09:54:37 | 显示全部楼层
谢啦,不过有需要的可以下载源码看看,都在里面的
回复 支持 反对

使用道具 举报

315

主题

253

回帖

0

蝴蝶豆

论坛元老

最后登录
2017-12-7
发表于 2015-7-27 09:56:04 | 显示全部楼层
谢谢楼主的分享
回复 支持 反对

使用道具 举报

47

主题

3404

回帖

30

蝴蝶豆

版主

最后登录
2020-12-7
发表于 2015-7-27 10:01:20 | 显示全部楼层
多谢分享。。。学习了
回复 支持 反对

使用道具 举报

3

主题

54

回帖

0

蝴蝶豆

中级会员

最后登录
2020-8-13
发表于 2015-7-27 10:05:25 | 显示全部楼层
好东西 多谢楼主了,
回复 支持 反对

使用道具 举报

7

主题

912

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-7-4
发表于 2015-7-27 11:36:43 | 显示全部楼层
上位机结合百度地图,就是个导航系统了。。
回复 支持 反对

使用道具 举报

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