背景
板子上有两个串口,但是串口1被xr829模块占用了,串口3主要用于调试,为简单实现串口功能,本讲将实现usb转串口(ch340)来采集gps的数据,并解析。
(一)USB串口驱动
@本讲不使用Tina系统,使用 百问Buildroot 。
Tips:CH340是CH341的阉割版,CH340不支持并口、打印口、IIC,专为串口应用设计
在buildroot已经集成了ch341的驱动,我们将其 使能 即可使用,非常简单。
Symbol: USB_SERIAL_CH341 [=y]
Type : tristate
Prompt: USB Winchiphead CH341 Single Port Serial Driver
Location:
-> Device Drivers
-> USB support (USB_SUPPORT [=y])
(1) -> USB Serial Converter support (USB_SERIAL [=y])
Defined at drivers/usb/serial/Kconfig:105
Depends on: USB_SUPPORT [=y] && USB [=y] && USB_SERIAL [=y]
(二)驱动加载
驱动是编译进内核的,不用手动加载,把USB转TTL插到USB口就自动匹配识别,生成ttyUSB0设备。
以下是开机显示信息:
[ 11.529946] usbcore: registered new interface driver ch341
[ 11.537840] usbserial: USB Serial support registered for ch341-uart
[ 11.545934] ch341 1-1.2:1.0: ch341-uart converter detected
[ 11.578483] usb 1-1.2: ch341-uart converter now attached to ttyUSB0
ls /dev
(三)简单读取串口数据
此时已经将ch340和gps模块连接上开发板了
使用 cat 命令即可简单读取串口返回的信息。
# cat /dev/ttyUSB0
A*7B
$GPVTG,,T,,M,1.070,N,1.982,K,A*27
$GPGGA,072008.00,2306.6$GPTXT,01,01,01,NMEA unknown msg*58
$GPRMC,072232.00,A,2306.62360,N,11316.59966,E,0.311,,020822,,,A*78
$GPVTG,,T,,M,0.311,N,0.577,K,A*25
$GPGGA,072232.00,2306.62360,N,11316.59966,E,1,08,1.62,21.7,M,-5.6,M,,*7A
$GPGSA,A,3,13,02,05,11,20,18,24,23,,,,,3.06,1.62,2.59*05
$GPGSV,3,1,11,02,49,126,20,05,43,034,37,11,28,123,12,13,58,033,35*72
$GPGSV,3,2,11,15,73,291,21,18,27,324,37,20,24,071,29,23,10,286,32*78
$GPGSV,3,3,11,24,26,175,20,29,48,259,10,30,06,046,*45
$GPGLL,2306.62360,N,11316.59966,E,072232.00,A,A*68
(四)数据解析
本解析参考: https://blog.csdn.net/qq_30665009/article/details/121434507
我们在编写正式的应用程序之前,先了解这一堆数据里面我们想要的部分 --> $GPRMC
$GPRMC格式:
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
$GPRMC,072232.00,A,2306.62360,N,11316.59966,E,0.311,,020822,,,A*78
其中:
(五)编写应用程序
参考 https://www.likecs.com/show-205110023.html
1、定义结构体
typedef struct __gprmc__
{
UINT time; /* gps定位时间 */
char pos_state; /*gps状态位*/
float latitude; /*纬度 */
float longitude; /* 经度 */
float speed; /* 速度 */
float direction; /*航向 */
UINT date; /*日期 */
float declination; /* 磁偏角 */
char dd;
char mode; /* GPS模式位 */
} GPRMC;
2、使用 open 和 read 函数读取串口数据
3、获取想要的部分
/* 如果buff字符串中包含字符"$GPRMC"则将$GPRMC的地址赋值给ptr */
if (NULL == (ptr = strstr(buff, "$GPRMC")))
{
return -1;
}
4、使用 sscanf 进行格式化处理,存进结构体
5、计算、回显处理
(六)测试
编译后放到开发板,测试程序
# ls
gps_test
# ./gps_test
buff:1,13,36,033,33*7F
$GPGSV,3,2,10,15,62,356,30,18,48,324,20,20,14,092,19,23,21,306,23*7A
$GPGSV,3,3,10,24,48,164,20,29,35,229,25*70
$GPGLL,2306.62377,N,11316.59930,E,081227.00,A,A*65
$GPRMC,081228.00,A,2306.62398,N,11316.59935,E,0.294,,020822,,,A*72
$GPVTG,,T,,M,0.294,N,0.545,K,A*28
$GPGGA,081228.00,2306.62398,N,11316.59935,E,1,08,1.04,-0.4,M,-5.6,M,,*61
$GPGSA,A,3,15,18,24,13,05,02,23,20,,,,,2.10,1.04,1.82*02
$GPGSV,3,1,10,02,29,144,21,05,36,062,35,11,10,138,,13,36,033,32*7E
$GPGSV,3,2,10,15,62,356,30,18,48,324,17,20,14,092,20,23,21,306,22*75
$GPGSV,3,3,10,24,48,164,20,29,35,229,26*73
$GPGLL,2306.62398,N,11316.59935,E,081228.00,A,A*6E
$GPRMC,081229.00,A,2306.62396,N,11316.59928,E,0.427,,020822,,,A*7F
$GPVTG,,T,,M,0.427,N,0.791,K,A*2D
$GPGGA,081229.00,2306.62396,N,11316.59928,E,1,09,1.04,-0.8,M,-5.6,M,,*6F
$GPGSA,A,3,15,18,24,13,05,02,23,20,11,,,,2.10,1.04,1.82*02
$GPGSV,3,1,10,02,29,144,21,05,36,062,35,11,10,138,1,1144,15,05,36,062,36,11,10,138,12)▒▒
===========================================================
==
== GPS state bit : A [A:有效状态 V:无效状态]
== GPS mode bit : A [A:自主定位 D:差分定位]
== Date : 2022-08-02
== Time : 16:12:28
== 纬度 : 北纬:23度6分37秒
== 经度 : 东经:113度16分35秒
== 速度 : 0.294 m/s
==
============================================================
但是要留意,某些gps模块获取不到该字段的数据,需要将其对应修改匹配。
至此,测试完毕。
源码地址:
https://download.csdn.net/download/qq_46079439/86272180
原文链接:https://blog.csdn.net/qq_46079439/article/details/126122756