搜索
查看: 14992|回复: 27

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

  [复制链接]

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

最后登录
2021-4-1
发表于 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, 下载次数: 338)

评分

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

查看全部评分

回复

使用道具 举报

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

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

使用道具 举报

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

最后登录
2021-4-1
 楼主| 发表于 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

主题

3432

帖子

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

主题

3432

帖子

0

蝴蝶豆

论坛元老

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

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

使用道具 举报

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

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

使用道具 举报

该用户从未签到

315

主题

568

帖子

0

蝴蝶豆

论坛元老

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

使用道具 举报

该用户从未签到

47

主题

3456

帖子

30

蝴蝶豆

版主

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

使用道具 举报

该用户从未签到

3

主题

57

帖子

0

蝴蝶豆

中级会员

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

使用道具 举报

该用户从未签到

7

主题

919

帖子

0

蝴蝶豆

金牌会员

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

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-1 08:34 , Processed in 1.219203 second(s), 42 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表