• 【全志T113-S3_100ask】8-USB串口获取GPS数据(含解析)


    背景

    板子上有两个串口,但是串口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]  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (二)驱动加载

    驱动是编译进内核的,不用手动加载,把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
    
    • 1
    • 2
    • 3
    • 4
    ls /dev
    
    • 1

    在这里插入图片描述

    (三)简单读取串口数据

    此时已经将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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    (四)数据解析

    本解析参考: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
    
     $GPRMC,072232.00,A,2306.62360,N,11316.59966,E,0.311,,020822,,,A*78
    
    • 1
    • 2
    • 3

    其中:

    字段解释
    字段 0$GPRMC,语句ID,表明该语句为推荐最小定位信息
    字段 1UTC时间,hhmmss.sss格式
    字段 2状态,A=定位,V=未定位
    字段 3纬度ddmm.mmmm,度分格式(前导位数不足则补0)
    字段 4纬度N(北纬)或S(南纬)
    字段 5经度dddmm.mmmm,度分格式(前导位数不足则补0)
    字段 6经度E(东经)或W(西经)
    字段 7速度,节,Knots(一节也是1.852千米/小时)
    字段 8方位角,度(二维方向指向,相当于二维罗盘)
    字段 9UTC日期,DDMMYY格式
    字段10磁偏角,(000 - 180)度(前导位数不足则补0)
    字段11磁偏角方向,E=东,W=西
    字段12模式,A=自动,D=差分,E=估测,N=数据无效(3.0协议内容)
    字段13校验值

    (五)编写应用程序

    参考 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、使用 open 和 read 函数读取串口数据
    3、获取想要的部分

    /* 如果buff字符串中包含字符"$GPRMC"则将$GPRMC的地址赋值给ptr */
    if (NULL == (ptr = strstr(buff, "$GPRMC")))
    {
        return -1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    ==   纬度 : 北纬:23637==   经度 : 东经:1131635==   速度 : 0.294  m/s
    ==
    ============================================================
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    但是要留意,某些gps模块获取不到该字段的数据,需要将其对应修改匹配。

    至此,测试完毕。
    源码地址:
    https://download.csdn.net/download/qq_46079439/86272180

  • 相关阅读:
    云计算实验4 面向行业背景的大数据分析与处理综合实验
    MySQL开窗函数
    mmrotate自定义数据集安装部署训练测试
    计算机网络工程毕业设计题目选题大全
    openGauss学习笔记-128 openGauss 数据库管理-设置透明数据加密(TDE)
    c语言初学者用vs还是vscode?
    小细节,大问题。分享一次代码优化的过程
    通过GFlags工具来复现因为野指针、内存越界等造成的程序崩溃
    MySQL日志系统知识点总结
    Java 通配符 在短信发送之中 通配符参数动态获取解决方案
  • 原文地址:https://blog.csdn.net/qq_46079439/article/details/126122756