RK3568平台(UART篇)uart应用编程读取模块数据

一.串口介绍

串口设备是嵌入式开发中最常用的外设之一,通过串口打印信息可以调试程序的运行,通 过串口也可以链接很多种外设,比如串口打印机,蓝牙,wifi,GPS,GPRS 等等。

数据传输方式:

串口通信使用的是串行传输方式,即将数据按照顺序一个一个地发送或接收。每个数据位 都在一定的时间间隔内发送或接收。串口使用两条数据线(TXD,RXD)和一条地线(GND) 进行传输。

数据格式:

串口通信使用的是异步传输方式,数据被分成固定大小的数据帧,每个数据帧由起始位、 数据位、校验位和停止位组成,通常称为“帧”。其中起始位和停止位用于标识数据帧的开始和 结束,校验位用于检验数据传输的准确性。数据位的数量一般为 7 位或 8 位。

波特率:

波特率是指数据传输的速度,也称为比特率,表示每秒钟可以传输多少个二进制数据位。 波特率越高,数据传输的速度就越快。常见的波特率有 9600bps、19200bps、38400bps、115200bps 等。

二.串口节点介绍

在嵌入式设备中,串口设备通常以字符设备节点的形式出现在 Linux 系统中。在 Linux 系 统中,每个设备都由一个设备节点(device node)来表示,设备节点是与设备相关联的一个文 件,以/dev 目录下的文件形式存在。 串口设备节点通常以 tty 开头,具体命名方式根据串口的类型和数量不同而不同。开发板 系统启动之后,使用以下命令打印终端设备节点。

查看串口ttyS2是否有数据输出:

cat /dev/ttyS2

 三.使用uart读取模块串口数据

下图为uart读取一帧数据,数据位所代表的解析:

串口编程:解析串口数据

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>

unsigned char *PM25_data;
unsigned char *VOC_data;
unsigned char *CO2_data;
unsigned char *Temp_Humi_data;


static void unpackMcuData(unsigned char *buf, int size)
{
    if (size < 5) {
        return;
    } 

    if (buf[0] != 0x55 && buf[1] != 0xaa) {
        return;
    }

    int dataSize = (int)buf[2];
    if ((buf[dataSize+ 2] != 0x0d) && (buf[dataSize + 2] != 0x0a)) {
        return;
    }

    unsigned char crc = 0;
    for (int i = 2; i < dataSize + 1; i++) {
        crc ^= buf[i];
    }

    if (crc != buf[dataSize + 1]) {
        return;
    }
    switch (buf[3]) {
        case 0x02 : {
            PM25_data = 0;
            PM25_data |= (((int)buf[9] & 0xff) << 8); //PM2.5 H
            PM25_data |= ((int)buf[10] & 0xff);        //PM2.5 L

            PM25_data |= (((int)buf[11] & 0xff) << 24); //PM10 H
            PM25_data |= (((int)buf[12] & 0xff) << 16); //PM10 L
            break;
        }
        case 0x03 : {
            VOC_data = 0;
            VOC_data |= (((int)buf[4] & 0xff) << 8); //VOC H
            VOC_data |= ((int)buf[5] & 0xff);        //VOC L
            break;
        }
        case 0x04 : {
            CO2_data = ((int)buf[8] & 0xff) * 256 + ((int)buf[9] & 0xff);
            break;
        }
        case 0x05 : {
            Temp_Humi_data = 0;
            Temp_Humi_data |= (((int)buf[4] & 0xff) << 24); //humi H
            Temp_Humi_data |= (((int)buf[5] & 0xff) << 16); //humi L
            Temp_Humi_data |= (((int)buf[6] & 0xff) << 8); //Temp H
            Temp_Humi_data |= ((int)buf[7] & 0xff);         //humi L
            break;
        }
        default : break;
    }
}

void *getMcuData(void *ptr)
{
    #if 1
    struct termios new_options, old_options;
    fd_set r_fds;
    struct timeval timeout;
    #define SET_IO_SPEED B115200
    static unsigned char _cmdLine[64];
    static unsigned int _u8ReceivedBytes = 0;
    int ret = 0;
    input_fd = open(MCU_TTY_PORT, O_RDWR| O_NOCTTY | O_NDELAY );
    if(input_fd == -1)
    {
        printf(" error open %s\n", MCU_TTY_PORT);
        return 0;
    }
    //fcntl(input_fd, F_SETFL, FNDELAY);
    tcgetattr(input_fd, &old_options); // 获取串口的设置选项
    // config ttyS0 not do local ECHO, turn off flow control
    tcgetattr(input_fd, &new_options);
    new_options.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | ISIG);
    new_options.c_iflag  &= ~(INPCK | INLCR | ICRNL | IUCLC | IXON | IXOFF);
    new_options.c_oflag  &= ~OPOST;   // raw output
    speed_t setiospeed=115200;
    cfsetispeed(&new_options, setiospeed);  // 设置波特率
    cfsetospeed(&new_options, setiospeed);
    tcsetattr(input_fd, TCSANOW, &new_options);  // 把新的设置应用到串口上
    
    while(1){

        timeout.tv_sec = 0;
        timeout.tv_usec = 10*1000; // 10 ms
        FD_ZERO(&r_fds);
        FD_SET(input_fd, &r_fds);
        ret = ::select(input_fd + 1, &r_fds, NULL, NULL, &timeout); //阻塞
        if(ret == 0)
        {
            continue;
        }
        else if(ret > 0 && FD_ISSET(input_fd, &r_fds))//else if(ret > 0)
        {
            ret = read(input_fd, _cmdLine, sizeof(_cmdLine)); //读取串口数据
            if(ret <= 0)
            {
                continue;
            }
            char str[128] = {0};
            sprintf(str, "recv: %02x %02x %02x %02x ", _cmdLine[0], _cmdLine[1], _cmdLine[2], _cmdLine[3]);
            printf(" 6 data %s\n", str);
            unpackMcuData(_cmdLine, ret);

        }
    }
    #endif
}

int main(void)
{
    pthread_t tid;
    pthread_attr_t thr_attr;
    pthread_attr_init(&thr_attr);
    if ((pthread_create(&tid, &thr_attr, getMcuData, (void *)NULL)) == -1){
        printf("getMcuData create error!\n");
        return -1;
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/641483.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ | Leetcode C++题解之第97题交错字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isInterleave(string s1, string s2, string s3) {auto f vector <int> (s2.size() 1, false);int n s1.size(), m s2.size(), t s3.size();if (n m ! t) {return false;}f[0] true;for (int i …

全同态加密生态项目盘点:FHE技术的崛起以及应用

撰文&#xff1a;Chris&#xff0c;Techub News 在当今数字化的时代&#xff0c;隐私保护已成为一个全球性的焦点话题&#xff0c;特别是在加密货币和区块链技术快速发展的背景下。虽然当前的隐私技术在保护数据安全方面多有欠缺&#xff0c;引发了广泛的关注和批评&#xff0c…

Java枚举的本质

目录 1.枚举简介 1.1.规范 1.2.枚举类真实的样子 1.3.枚举类的特点 1.4.枚举可以使用的方法 1.4.1.toString()方法 1.4.2.valueOf方法 1.4.3.values方法 1.4.4.ordinal方法 1.5.枚举的用法 1.5.1.常量 1.5.2.switch 1.5.3.枚举中增加方法 1.5.4.覆盖枚举方法 1.5…

热题系列章节1

22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”] 示例 2&#xff1a…

LeetCode/NowCoder-链表经典算法OJ练习3

孜孜不倦&#xff1a;孜孜&#xff1a;勤勉&#xff0c;不懈怠。指工作或学习勤奋不知疲倦。&#x1f493;&#x1f493;&#x1f493; 目录 说在前面 题目一&#xff1a;返回倒数第k个节点 题目二&#xff1a;链表的回文结构 题目三&#xff1a;相交链表 SUMUP结尾 说在前…

两篇文章讲透数据结构之堆(一)!

目录 1.堆的概念 2.堆的实现方式 3.堆的功能 4.堆的声明 5.堆的实现 5.1堆的初始化 5.2堆的插入 5.2.1向上调整算法 5.2.2堆的插入 5.3堆的删除 5.3.1向下调整算法 5.3.2堆的删除 5.4获取堆顶元素 5.5获取堆的元素个数 5.6判断堆是否为空 5.7打印堆 5.8建堆 …

SQL开窗函数

文章目录 概念&#xff1a;语法&#xff1a;常用的窗口函数及示例&#xff1a;求平均值&#xff1a;AVG() &#xff1a;求和&#xff1a;SUM():求排名&#xff1a;移动平均计数COUNT():求最大MXA()/小MIN()值求分区内的最大/最小值求当前行的前/后一个值 概念&#xff1a; 开窗…

算法题1:电路开关(HW)

题目描述 实验室对一个设备进行通断测试,实验员可以操控开关进行通断,有两种情况: ps,图没记下来,凭印象画了类似的 初始时,3个开关的状态均为断开;现给定实验员操控记录的数组 records ,records[i] = [time, switchId],表示在时刻 time 更改了开关 switchId 的状态…

多线程(C++11)

多线程&#xff08;C&#xff09; 文章目录 多线程&#xff08;C&#xff09;前言一、std::thread类1.线程的创建1.1构造函数1.2代码演示 2.公共成员函数2.1 get_id()2.2 join()2.3 detach()2.4 joinable()2.5 operator 3.静态函数4.类的成员函数作为子线程的任务函数 二、call…

AOP编程

AOP编程 AOP&#xff0c;面向切面编程&#xff0c;一种编程范式&#xff0c;指导开发者如何组织程序结构。 OOP&#xff0c;面向对象编程&#xff0c;一种编程思想。 AOP&#xff0c;提供了一种机制,可以将一些横切系统中多个模块的共同逻辑(如日志记录、事务管理、安全控制等…

SQL面试题练习 —— 波峰波谷

来源&#xff1a;字节今日头条 目录 1 题目2 建表语句3 题解 1 题目 有如下数据&#xff0c;记录每天每只股票的收盘价格&#xff0c;请查出每只股票的波峰和波谷的日期和价格&#xff1b; 波峰定义&#xff1a;股票价格高于前一天和后一天价格时为波峰 波谷定义&#xff1a;股…

MoE 系列论文解读:Gshard、FastMoE、Tutel、MegaBlocks 等

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接…

Unity在Windows平台播放HEVC/H.265格式视频的底层原理

相关术语、概念 HEVC/H.265 HEVC&#xff08;High Efficiency Video Coding&#xff09;是一种视频压缩标准&#xff0c;也被称为H.265。它是一种高效的视频编码标准&#xff0c;可以提供比之前的标准&#xff08;如H.264&#xff09;更高的压缩率&#xff0c;同时保持较高的…

力扣HOT100 - 31. 下一个排列

解题思路&#xff1a; 数字是逐步增大的 步骤如下&#xff1a; class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) i--;if (i > 0) {int j nums.length - 1;while (j > 0 &&…

015_表驱动编程思想(c实现)

【背景】 数据压倒一切。如果选择了正确的数据结构并把一切组织的井井有条&#xff0c;正确的算法就不言自明。编程的核心是数据结构&#xff0c;而不是算法。 ——Rob Pike 上面是这个名人说过的话&#xff0c;那么c语言之父 丹尼斯麦卡利斯泰尔里奇 的《c程序设计》里曾经…

【Linux取经路】基于信号量和环形队列的生产消费者模型

文章目录 一、POSIX 信号量二、POSIX 信号量的接口2.1 sem_init——初始化信号量2.2 sem_destroy——销毁信号量2.3 sem_wait——等待信号量2.4 sem_post——发布信号量 三、基于环形队列的生产消费者模型3.1 单生产单消费模型3.2 多生产多消费模型3.3 基于任务的多生产多消费模…

C# 利用Xejen框架源码,我们来开发一个基于Dapper技术的数据库通用的帮助访问类,通过Dapper的增删改查,可以访问Sqlite数据库

Dapper 是一个轻量级的对象关系映射&#xff08;ORM&#xff09;工具&#xff0c;适用于 .NET 平台。它由 Stack Overflow 团队开发&#xff0c;旨在提供简单、高效的数据访问功能。与其他重量级 ORM&#xff08;如 Entity Framework&#xff09;相比&#xff0c;Dapper 更加轻…

用这8种方法在海外媒体推广发稿平台上获得突破-华媒舍

在今天的数字时代&#xff0c;海外媒体推广发稿平台已经成为了许多机构和个人宣传和推广的有效途径。如何在这些平台上获得突破并吸引更多的关注是一个关键问题。本文将介绍8种方法&#xff0c;帮助您在海外媒体推广发稿平台上实现突破。 1. 确定目标受众 在开始使用海外媒体推…

C++语法|虚函数与多态详细讲解(六)|如何解释多态?(面试向)

系列汇总讲解&#xff0c;请移步&#xff1a; C语法&#xff5c;虚函数与多态详细讲解系列&#xff08;包含多重继承内容&#xff09; 多态分为了两种&#xff0c;一种是静态的多态&#xff0c;一种是动态的多态。 静态&#xff08;编译时期&#xff09;的多态 函数重载 boo…

pands使用openpyxl引擎实现EXCEL条件格式

通过python的openpyxl库&#xff0c;实现公式条件格式。 实现内容&#xff1a;D列单元格不等于E列同行单元格时标红。 #重点是formula后面的公式不需要“”号。 from openpyxl.styles import Color, PatternFill, Font, Border from openpyxl.styles.differential import Dif…