在线时间585 小时
UID3520860
注册时间2020-11-9
NXP金币216
TA的每日心情 | 奋斗 昨天 08:00 |
---|
签到天数: 554 天 [LV.9]以坛为家II
版主
- 积分
- 5604
- 最后登录
- 2024-3-28
|
发表于 2021-7-30 09:17:18
|
显示全部楼层
回帖奖励 +2 NXP金币
书接上回——上回书在此,上次咱们介绍的如何利用I2C接口接入传感器,这篇文章介绍是如何通过UART连接北斗/GPS模块获取地理位置信息,智慧物流嘛北斗/GPS是传统位置追踪的手段,也可以利用GPS模块给出的时间数据进行校时。
一、北斗/GPS模块介绍
GPS购于某宝,类似的厂商有很多知名的有Ublox,,移远等,我这里买的是中科微的,别问为什么选它,问就是便宜... 而且这个模块尺寸小、支持全GNSS系统(北斗、GPS、GLONASS、伽利略、日本的QZSS以及卫星增强系统SBAS)。
1、接MCU的UART
模块引脚说明如下
GPS模块引脚实际与LPC55S69-IOT kit连接的时候,可以按照如下接法,模块的RX可以不接,看要不要配置模块了,如果不需要配置GPS模块则可以不接的。
2、GPS模块的数据格式- NEMA码
我们可以先用USB转UART的dongle来看看NEMA长什么样子,本狮这里用的是CP2102的模块,用sscom串口助手来接受GPS模块发出来的数据。数据有点多,但是别怕,之后我们先认真分析下后用“拥抱(CTRL+C) +开源(CTRL+V)”的方式给大家节约点时间,毕竟工作后键盘磨秃的不再是AWSD了~
下面是模块输出的数据:
这里本狮说的NEMA码指的是NMEA-0183协议的报文,大多数常见的GNSS接收机、GNSS数据处理软件、导航软件都遵守或者兼容这个协议。
数据里面我们看到三种数据类型GN、GP、BD 分别代表双模模式、GPS 模式、北斗模式。比如下面这条报文:
根据NMEA-0183协议的规定,$XXGGA报文是关于时间、经纬度位置、解算状态、卫星颗数等相关信息。XX的不同代表模式的不同,比如$GPGGA表示单GPS模式,$BDGGA表示单北斗模式,$GNGGA表示多星联合定位。具体的含义我们对应查表就行了(NEMA-0193协议),微信小文章就不放了,论坛的帖子里我会放具体的表格,定位不一样。
二、MCU如何获取NEMA码并且解析
一般来说GPS模块都是和MCU的串口连接的,串口接收数据的方式无非三种,轮询Polling/中断Interrupt/DMA。轮询基本上是不可能选择的模式,所以大多数用户还是用的中断,高阶点的则用DMA的方式。
1、中断的方式
中断的方式虽说占用些MCU的资源,但是胜在串口是低速率的并且简单易移植,如果系统设备始终中断资源较少的话影响还好。
2、DMA的方式
DMA的方式比较推荐,占用CPU的资源少,一般来说要配置UART的接收完成(Received Idle)信号来完成一次数据的接收,并且启动下一次DMA从串口到RAM的搬运工作。但是LPC55系列除了LPC55S3x系列的UART带有Received Idle的功能,其他的比如LPC55S0x、LPC55S1x、LPC55S2x、LPC55S6x都不具备此模式,所以针对这种没有Received Idle的MCU,我们只能启动一个定时器来做Timeout管理。
3、代码中如何识别
咱们可以用strstr的方式去获取GPS的数据头帧的信息,比如:
- if(g_GPRSecvCnt>=GPS_BUFFER_SIZE)
- {
- uint8_t*buff=NULL;
- buf=(uint8_t*)strstr((const char*)g_GPRSecvBuf,"SGNRMC,");
- if(buf !=null)
- {
[color=rgb(51, 102, 153) !important]复制代码
4、借助开源
Github上关于GPS的NEMA解码有现成的code,比如GPSNMEAparser,现在作者改名叫lwgps了,license比较友好MIT的,基于ANSI C99l垒的码移植起来也很简单,具体见论坛的帖子。
API使用介绍
第一步,声明全局句柄lwgps_t hgps;
第二步,初始化lwgps_init(&hgps);
第三步,在while(1)或者任务中调用lwgpsprocess(&hgps, gpsrxdata, strlen(gpsrx_data));
剩下的就可以通过,hgps.is_valid来判断GPS模块是否定位成功,如果定位成功则hgps.latitude和hgps.longitude就是经纬度数据,hgps.altitude就是高度数据。当然也可以通过hgps的date,month,year等获取时间数据,hpgs.speed获取速度数据等等。具体参考hgps的定义即可。
三、附加知识
如果你GPS的实际数据上传到百度或者高德地图的话,多半会和你实际的地理位置差了几公里...那是因为你的GPS模块吐出来的一般是WGS84坐标系,百度地图用的是BD-09坐标系,高德地图用的是GCJ-02坐标系。
国外的地图服务商可能会用WGS84坐标系... 数据偏移的算法也不难,网上可查,但是作为一个CTRL+C/V的程序员还是推荐一个开源的代码库ChinaMapShift,license依旧是友好的MIT。
API使用介绍
第一步,声明 WGS84和 GCJ02句柄
Location WGS84;
Location GCJ02;
第二步,将GPS输出的合法的WGS84坐标系的数据赋值给WGS84
WGS84.lat = hgps.latitude;
WGS84.lng = hgps.longitude;
第三步,调用transformFromWGSToGCJ()
GCJ02 = transformFromWGSToGCJ(WGS84);
剩下的,GCJ02.lat以及GCJ02.lng就是GCJ02坐标系下的经纬度数据了。
本人水平有限,非常欢迎大家分享如何使用GPS模块的技巧。
上篇回顾:
用LPC55xx搭建AIOT平台,步骤分解之传感器篇
|
|