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

查看: 2279|回复: 9

【HAL库每天一例】第090例:GPS模块NEO-7M_GPS-USART && LCD显示

[复制链接]

122

主题

129

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-5-28
发表于 2016-8-11 09:12:54 | 显示全部楼层 |阅读模式
本帖最后由 haohao663 于 2016-8-11 14:12 编辑

【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。

例程下载:
资料包括程序、相关说明资料以及软件使用截图

百度云盘:https://pan.baidu.com/s/1slN8rIt 密码:u6m1
360云盘:http://yunpan.cn/OcPiRp3wEcA92u密码 cfb6
(硬石YS-F1Pro开发板HAL库例程持续更新\2. 软件设计之高级裸机例程(HAL库版本)\YSF1_HAL-122. GPS模块NEO-7M
/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: 2. GPS-USART
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:硬石电子社区
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
    UBLOX NEO-7M模块是一款高性能的GPS定位模块,是NEO-6M升级版GPS模块,该模块能满足专业定
位的严格要求, 模块带陶瓷有缘天线,信号超强。EEPROM掉电保存配置参数数据。

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg
CubeMX_4.jpg
CubeMX_5.jpg
CubeMX_6.jpg
CubeMX_7.jpg
CubeMX_8.jpg
CubeMX_9.jpg
CubeMX_10.jpg



nmea_decode_test.c文件内容
  1. /* 包含头文件 ----------------------------------------------------------------*/
  2. #include "stm32f1xx_hal.h"
  3. #include "usart/bsp_debug_usart.h"
  4. #include "ff.h"
  5. #include "nmea/nmea.h"
  6. #include "gps/bsp_gps_usartx.h"

  7. /* 私有类型定义 --------------------------------------------------------------*/
  8. /* 私有宏定义 ----------------------------------------------------------------*/
  9. /* 私有变量 ------------------------------------------------------------------*/
  10. #ifdef __GPS_LOG_FILE             //对SD卡上的gpslog.txt文件进行解码;(需要在sd卡上存放gpslog.txt文件)
  11. FIL file;                                                                                                        /* 文件对象 */
  12. UINT fnum;                                                      /* 文件成功读写数量 */
  13. char buff[2048];

  14. #else

  15. uint8_t gps_rbuff[GPS_RBUFF_SIZE];
  16. __IO uint8_t GPS_TransferEnd = 0, GPS_HalfTransferEnd = 0;

  17. #endif  

  18. /* 扩展变量 ------------------------------------------------------------------*/
  19. #ifdef __GPS_LOG_FILE             //对SD卡上的gpslog.txt文件进行解码;(需要在sd卡上存放gpslog.txt文件)
  20. extern FRESULT f_res;                    /* 文件操作结果 */
  21. #endif

  22. /* 私有函数原形 --------------------------------------------------------------*/
  23. /* 函数体 --------------------------------------------------------------------*/
  24. /**
  25.   * 函数功能: trace 在解码时输出捕获的GPS语句
  26.   * 输入参数: 无
  27.   * 返 回 值: 无
  28.   * 说    明:str: 要输出的字符串,str_size:数据长度
  29.   */
  30. void trace(const char *str, int str_size)
  31. {
  32. #ifdef __GPS_DEBUG    //配置这个宏,是否输出调试信息
  33.     uint16_t i;
  34.     printf("\r\nTrace: ");
  35.     for(i=0;i<str_size;i++)
  36.       printf("%c",*(str+i));
  37.   
  38.     printf("\n");
  39. #endif
  40. }

  41. /**
  42.   * 函数功能: error 在解码出错时输出提示消息
  43.   * 输入参数: 无
  44.   * 返 回 值: 无
  45.   * 说    明:str: 要输出的字符串,str_size:数据长度
  46.   */
  47. void error(const char *str, int str_size)
  48. {
  49. #ifdef __GPS_DEBUG   //配置这个宏,是否输出调试信息

  50.     uint16_t i;
  51.     printf("\r\nError: ");
  52.     for(i=0;i<str_size;i++)
  53.       printf("%c",*(str+i));
  54.     printf("\n");
  55. #endif
  56. }

  57. /**
  58.   * 函数功能: 判断闰年(仅针对于2000以后的年份)
  59.   * 输入参数: iYear    两位年数
  60.   * 返 回 值: uint8_t        1:为闰年    0:为平年
  61.   * 说    明:无
  62.   */
  63. static uint8_t IsLeapYear(uint8_t iYear)
  64. {
  65.     uint16_t    Year;
  66.     Year    =    2000+iYear;
  67.     if((Year&3)==0)
  68.     {
  69.         return ((Year%400==0) || (Year%100!=0));
  70.     }
  71.      return 0;
  72. }

  73. /**
  74.   * 函数功能: 格林尼治时间换算世界各时区时间
  75.   * 输入参数: *DT:表示日期时间的数组 格式 YY,MM,DD,HH,MM,SS
  76.   * 返 回 值: 无
  77.   * 说    明:AREA:1(+)东区 W0(-)西区   GMT:时区数
  78.   */
  79. void    GMTconvert(nmeaTIME *SourceTime, nmeaTIME *ConvertTime, uint8_t GMT,uint8_t AREA)
  80. {
  81.     uint32_t    YY,MM,DD,hh,mm,ss;        //年月日时分秒暂存变量
  82.      
  83.     if(GMT==0)    return;                //如果处于0时区直接返回
  84.     if(GMT>12)    return;                //时区最大为12 超过则返回         

  85.     YY    =    SourceTime->year;                //获取年
  86.     MM    =    SourceTime->mon;                 //获取月
  87.     DD    =    SourceTime->day;                 //获取日
  88.     hh    =    SourceTime->hour;                //获取时
  89.     mm    =    SourceTime->min;                 //获取分
  90.     ss    =    SourceTime->sec;                 //获取秒

  91.     if(AREA)                        //东(+)时区处理
  92.     {
  93.         if(hh+GMT<24)    hh    +=    GMT;//如果与格林尼治时间处于同一天则仅加小时即可
  94.         else                        //如果已经晚于格林尼治时间1天则进行日期处理
  95.         {
  96.             hh    =    hh+GMT-24;        //先得出时间
  97.             if(MM==1 || MM==3 || MM==5 || MM==7 || MM==8 || MM==10)    //大月份(12月单独处理)
  98.             {
  99.                 if(DD<31)    DD++;
  100.                 else
  101.                 {
  102.                     DD    =    1;
  103.                     MM    ++;
  104.                 }
  105.             }
  106.             else if(MM==4 || MM==6 || MM==9 || MM==11)                //小月份2月单独处理)
  107.             {
  108.                 if(DD<30)    DD++;
  109.                 else
  110.                 {
  111.                     DD    =    1;
  112.                     MM    ++;
  113.                 }
  114.             }
  115.             else if(MM==2)    //处理2月份
  116.             {
  117.                 if((DD==29) || (DD==28 && IsLeapYear(YY)==0))        //本来是闰年且是2月29日 或者不是闰年且是2月28日
  118.                 {
  119.                     DD    =    1;
  120.                     MM    ++;
  121.                 }
  122.                 else    DD++;
  123.             }
  124.             else if(MM==12)    //处理12月份
  125.             {
  126.                 if(DD<31)    DD++;
  127.                 else        //跨年最后一天
  128.                 {               
  129.                     DD    =    1;
  130.                     MM    =    1;
  131.                     YY    ++;
  132.                 }
  133.             }
  134.         }
  135.     }
  136.     else
  137.     {     
  138.         if(hh>=GMT)    hh    -=    GMT;    //如果与格林尼治时间处于同一天则仅减小时即可
  139.         else                        //如果已经早于格林尼治时间1天则进行日期处理
  140.         {
  141.             hh    =    hh+24-GMT;        //先得出时间
  142.             if(MM==2 || MM==4 || MM==6 || MM==8 || MM==9 || MM==11)    //上月是大月份(1月单独处理)
  143.             {
  144.                 if(DD>1)    DD--;
  145.                 else
  146.                 {
  147.                     DD    =    31;
  148.                     MM    --;
  149.                 }
  150.             }
  151.             else if(MM==5 || MM==7 || MM==10 || MM==12)                //上月是小月份2月单独处理)
  152.             {
  153.                 if(DD>1)    DD--;
  154.                 else
  155.                 {
  156.                     DD    =    30;
  157.                     MM    --;
  158.                 }
  159.             }
  160.             else if(MM==3)    //处理上个月是2月份
  161.             {
  162.                 if((DD==1) && IsLeapYear(YY)==0)                    //不是闰年
  163.                 {
  164.                     DD    =    28;
  165.                     MM    --;
  166.                 }
  167.                 else    DD--;
  168.             }
  169.             else if(MM==1)    //处理1月份
  170.             {
  171.                 if(DD>1)    DD--;
  172.                 else        //新年第一天
  173.                 {               
  174.                     DD    =    31;
  175.                     MM    =    12;
  176.                     YY    --;
  177.                 }
  178.             }
  179.         }
  180.     }         

  181.     ConvertTime->year   =    YY;                //更新年
  182.     ConvertTime->mon    =    MM;                //更新月
  183.     ConvertTime->day    =    DD;                //更新日
  184.     ConvertTime->hour   =    hh;                //更新时
  185.     ConvertTime->min    =    mm;                //更新分
  186.     ConvertTime->sec    =    ss;                //更新秒
  187. }  


  188. #ifdef __GPS_LOG_FILE             //对SD卡上的gpslog.txt文件进行解码;(需要在sd卡上存放gpslog.txt文件)
  189. /**
  190.   * 函数功能: 对SD卡内的文件解码GPS文件信息
  191.   * 输入参数: 无
  192.   * 返 回 值: 无
  193.   * 说    明:无
  194.   */
  195. void nmea_decode_test(void)
  196. {
  197.   nmeaINFO info;          //GPS解码后得到的信息
  198.   nmeaPARSER parser;      //码时使用的数据结构  
  199.   
  200.   nmeaTIME beiJingTime;    //北京时间

  201.   /* 打开记录有GPS信息的文件 */
  202.   f_res = f_open(&file,"gpslog.txt", FA_OPEN_EXISTING|FA_READ);
  203.   printf("f_res=%d",f_res);
  204.   if(!(f_res == FR_OK))
  205.   {     
  206.     printf("\r\n打开gpslog.txt文件失败,请检查SD卡的根目录是否存放了gpslog.txt文件!\r\n");
  207.     return ;      
  208.   }
  209.   /* 设置用于输出调试信息的函数 */
  210.   nmea_property()->trace_func = &trace;
  211.   nmea_property()->error_func = &error;

  212.   /* 初始化GPS数据结构 */
  213.   nmea_zero_INFO(&info);
  214.   nmea_parser_init(&parser);

  215.   while(!f_eof(&file))
  216.   {
  217.    
  218.     f_read(&file, &buff[0], 100, &fnum);

  219.     /* 进行nmea格式解码 */
  220.     nmea_parse(&parser, &buff[0], fnum, &info);
  221.   
  222.     /* 对解码后的时间进行转换,转换成北京时间 */
  223.     GMTconvert(&info.utc,&beiJingTime,8,1);
  224.    
  225.     /* 输出解码得到的信息 */
  226.     printf("\n时间%d,%d,%d,%d,%d,%d\n", beiJingTime.year+1900, beiJingTime.mon+1,beiJingTime.day,beiJingTime.hour,beiJingTime.min,beiJingTime.sec);
  227.     printf("纬度:%f,经度%f\n",info.lat/100,info.lon/100);
  228.     printf("正在使用的卫星:%d,可见卫星:%d\n",info.satinfo.inuse,info.satinfo.inview);
  229.     printf("海拔高度:%f 米 \n", info.elv);
  230.     printf("速度:%f km/h \n", info.speed);
  231.     printf("航向:%f 度\n", info.direction);
  232.         }
  233.   f_lseek(&file, f_size(&file));

  234.   /* 释放GPS数据结构 */
  235.   nmea_parser_destroy(&parser);  
  236.   /* 关闭文件 */
  237.   f_close(&file);
  238. }


  239. #else

  240. void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
  241. {
  242.   GPS_HalfTransferEnd=1;
  243. }

  244. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  245. {
  246.   GPS_TransferEnd=1;
  247. }

  248. /**
  249.   * 函数功能: 解码GPS模块信息
  250.   * 输入参数: 无
  251.   * 返 回 值: 无
  252.   * 说    明:无
  253.   */
  254. int nmea_decode_test(void)
  255. {
  256.   nmeaINFO info;          //GPS解码后得到的信息
  257.   nmeaPARSER parser;      //解码时使用的数据结构  
  258.   uint8_t new_parse=0;    //是否有新的解码数据标志

  259.   nmeaTIME beiJingTime;    //北京时间

  260.   /* 设置用于输出调试信息的函数 */
  261.   nmea_property()->trace_func = &trace;
  262.   nmea_property()->error_func = &error;

  263.   /* 初始化GPS数据结构 */
  264.   nmea_zero_INFO(&info);
  265.   nmea_parser_init(&parser);
  266.   
  267.   /* 使用DMA传输数据到电脑端 */
  268.   HAL_UART_Receive_DMA(&husartx,gps_rbuff,GPS_RBUFF_SIZE);  
  269.   
  270.   while(1)
  271.   {
  272.     if(GPS_HalfTransferEnd)     /* 接收到GPS_RBUFF_SIZE一半的数据 */
  273.     {
  274.       /* 进行nmea格式解码 */
  275.       nmea_parse(&parser, (const char*)&gps_rbuff[0], HALF_GPS_RBUFF_SIZE, &info);
  276.       GPS_HalfTransferEnd = 0;   //清空标志位
  277.       new_parse = 1;             //设置解码消息标志
  278.     }
  279.     else if(GPS_TransferEnd)    /* 接收到另一半数据 */
  280.     {         
  281.       nmea_parse(&parser, (const char*)&gps_rbuff[HALF_GPS_RBUFF_SIZE], HALF_GPS_RBUFF_SIZE, &info);
  282.       GPS_TransferEnd = 0;
  283.       new_parse =1;
  284.     }
  285.     if(new_parse )                //有新的解码消息   
  286.     {            
  287.       /* 对解码后的时间进行转换,转换成北京时间 */
  288.       GMTconvert(&info.utc,&beiJingTime,8,1);      
  289.       /* 输出解码得到的信息 */
  290.       printf("\n时间%d,%d,%d,%d,%d,%d\n", beiJingTime.year+1900, beiJingTime.mon+1,beiJingTime.day,beiJingTime.hour,beiJingTime.min,beiJingTime.sec);
  291.       printf("纬度:%f,经度%f\n",info.lat/100,info.lon/100);
  292.       printf("正在使用的卫星:%d,可见卫星:%d\n",info.satinfo.inuse,info.satinfo.inview);
  293.       printf("海拔高度:%f 米 \n", info.elv);
  294.       printf("速度:%f km/h \n", info.speed);
  295.       printf("航向:%f 度\n", info.direction);      
  296.       new_parse = 0;
  297.     }
  298.   }
  299. }

  300. #endif // #ifdef __GPS_LOG_FILE

  301. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码



<
回复

使用道具 举报

100

主题

3617

回帖

1

蝴蝶豆

论坛元老

最后登录
2020-12-8
发表于 2016-8-15 09:41:32 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

16

回帖

0

蝴蝶豆

初级会员

最后登录
2020-6-19
发表于 2016-9-28 14:35:38 | 显示全部楼层
找到了,谢谢
回复 支持 反对

使用道具 举报

10

主题

1651

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-2-15
发表于 2016-9-28 17:09:18 | 显示全部楼层
看着楼主的贴学习的。
回复 支持 反对

使用道具 举报

1

主题

55

回帖

5

蝴蝶豆

金牌会员

最后登录
2020-8-24
发表于 2016-9-28 18:42:52 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

47

主题

1210

回帖

5

蝴蝶豆

论坛元老

最后登录
2020-8-13
发表于 2016-9-29 00:41:43 | 显示全部楼层
感谢分享
mcust.png
回复 支持 反对

使用道具 举报

38

主题

542

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-11
发表于 2016-10-2 09:40:47 | 显示全部楼层
学习学习                  
回复 支持 反对

使用道具 举报

4

主题

484

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-8-12
发表于 2016-11-18 07:19:17 来自手机 | 显示全部楼层
谢楼主分享
回复 支持 反对

使用道具 举报

11

主题

1139

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-7-10
发表于 2016-11-19 01:01:36 | 显示全部楼层
楼主费心了
回复 支持 反对

使用道具 举报

10

主题

693

回帖

0

蝴蝶豆

金牌会员

最后登录
2018-6-15
发表于 2016-11-27 22:22:21 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

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