树莓派多串口通信

树莓派多串口通信

  • 串口配置
  • 串口通信函数分析
  • 串口通信示例代码

  • 参考博文1:树莓派 4 UART 多串口配置通信
  • 参考博文2:树莓派wiringPi库详解
  • 关于树莓派相关其他环境配置可参考:快速上手树莓派
  • 关于wiringPi库初始化与IO口开发可参考:树莓派外设开发-GPIO口

考虑到SSH网络时常出现小问题,因此本人将树莓派串口1(ttyAMA0)主要用于树莓派串口登陆备份,本文主要对串口2-串口5进行配置开发,同时也会涉及对串口1通信的配置。

串口配置

配置开启串口 UART2-5
执行编辑 config.txt 命令:

sudo nano /boot/config.txt

在文件结尾添加如下:

dtoverlay=uart2
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5

保存(Ctrl + o)并退出(Ctrl + x)

重启(sudo reboot)后查看是否生效:

ls /dev/ttyAMA*

结果显示如下:

pi@raspberrypi:~ $ ls /dev/ttyAMA*
/dev/ttyAMA0  /dev/ttyAMA1  /dev/ttyAMA2  /dev/ttyAMA3  /dev/ttyAMA4

各 UART 串口与 GPIO 对应关系:
这里的GPIO对应的是BCM码,不是wPi码

GPIO14 = TXD0 -> ttyAMA0
GPIO15 = RXD0 -> ttyAMA0

GPIO0  = TXD2 -> ttyAMA1
GPIO1  = RXD2 -> ttyAMA1

GPIO4  = TXD3 -> ttyAMA2
GPIO5  = RXD3 -> ttyAMA2

GPIO8  = TXD4 -> ttyAMA3
GPIO9  = RXD4 -> ttyAMA3

GPIO12 = TXD5 -> ttyAMA4
GPIO13 = RXD5 -> ttyAMA4

查看树莓派GPIO引脚编号:gpio readall
注意:查看时,将树莓派的USB接口面对自己,别反了😂
在这里插入图片描述

串口通信函数分析

使用时需要包含头文件:#include <wiringSerial.h>
打开串口

int serialOpen (char *device, int baud)
device : 串口的地址,在Linux中就是设备所在的目录。默认一般是`"/dev/ttyAMA1"`这种, 我的是这样的。
baud   : 波特率 通常为 `9600` 
返回    : 成功返回文件描述符,失败返回-1

获取串口缓存中字节数

int serialDataAvail (int fd)
fd  : 文件描述符
返回 : 串口缓存中已经接收的,可读取的字节数,-1代表错误

发送一个字节

void  serialPutchar (int fd, unsigned char c)	
fd: 文件描述符
c : 要发送的字符数据

读取一个字节

int serialGetchar (int fd)	
fd  : 文件描述符
返回 : 读取到的字符

从串口读取一个字节数据返回,如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1
所以,在读取前,最好需要通过serialDataAvail判断是否有数据

发送字符串

#include <unistd.h>
size_t write (int fd,const void * buf,size_t count)
fd    : 文件描述符
buf   : 需要发送的数据缓存数组
count : 发送buf中的前count个字节数据
返回   : 实际写入的字符数,错误返回-1

接收字符串

#include <unistd.h>
*size_t read(int fd,void * buf ,size_t count);	
fd    : 文件描述符
buf   : 接收的数据缓存的数组
count : 接收的字节数.
返回  : 实际读取的字符数。	

当要接收的数据量过大时,wiringPi建议使用write和read函数。
接收到的buf可通过strstr和strchar来判断是否存在子串和特定字符,或者使用switch扫描不同情况。

串口通信示例代码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <wiringSerial.h>
#include <wiringPi.h>
#include "pthread.h"
#include <stdlib.h>

int fd;

void *write_thread(void *datas)
{
    char send_buf[]="hello world";
    char cmd;
    while(1)
    {
        printf("pthread1:按任意键发送数据\n");
        scanf("%c",&cmd);
        write(fd, send_buf, strlen(send_buf));  //测试发送数据
    }
}

void *read_thread(void *datas)
{
    int nread;
    char msg[128]={'\0'};
    printf("pthread2:listing......\n");
    while(1)
    {
        while(serialDataAvail(fd)!=-1 ) //串口有数据
        {
            nread=read(fd, msg,128);    //读取并保存数据
            if(nread==0)
                continue;
            printf("get data:%d Byte context:%s\n",nread,msg);
            printf("pthread2:listing......\n");
            memset(msg,0,strlen(msg));
        }
    }
}

int main()
{

    pthread_t writeThread;
    pthread_t readThread;


    if(-1==wiringPiSetup())
    {
        printf("setup error\n");
        exit(-1);
    }

    //请开启实验对应的串口即可, 若同时用到多个串口,注意变量命名
    //fd = serialOpen("/dev/ttyAMA1",9600); //打开ttyAMA1
    //fd = serialOpen("/dev/ttyAMA2",9600); //打开ttyAMA2
    //fd = serialOpen("/dev/ttyAMA3",9600); //打开ttyAMA3
    fd = serialOpen("/dev/ttyAMA4",9600);   //打开ttyAMA4

    pthread_create(&writeThread,NULL, write_thread,NULL);   //创建串口发送线程
    pthread_create(&readThread, NULL, read_thread, NULL);   //创建串口接收线程

    pthread_join(writeThread,NULL);
    pthread_join(readThread, NULL);

    return 0;
}

程序运行结果如下所示,串口收发自如
在这里插入图片描述

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

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

相关文章

OpenLayer库的学习入门总结

前言&#xff1a; 作者跟随视频学习ol库的调用与功能实现&#xff0c;进行初步总结与回顾。 声明&#xff1a;参考新中地的文档&#xff0c;进行作者日后复习再次学习的简化。 1、WebGIS简介 GIS的核心概念 GIS&#xff08;Geographic Information System&#xff09;是一…

第 374 场 LeetCode 周赛题解

A 找出峰值 枚举 class Solution { public:vector<int> findPeaks(vector<int> &mountain) {int n mountain.size();vector<int> res;for (int i 1; i < n - 1; i)if (mountain[i] > mountain[i - 1] && mountain[i] > mountain[i 1…

中断方式的数据接收2

Echo实验 回忆之前的实验因为数据处理的过程可以瞬间完成所以可以把数据处理的操作放在中断服务函数中执行 但是数据处理要是时间过长就将数据缓存处理 当使用中断方式接收数据的时候 一般有两种方式 数据处理的时间较短可放在中断服务函数内处理&#xff08;就地处理&#…

【Linux--进程】

目录 一、基本概念1.1描述进程-PCB1.2task_struct中内容分类 二、了解进程2.1查看进程2.2通过系统调用获取进程标识符 三、fork创建进程3.1fork()函数3.2写时拷贝 四、进程的状态4.1操作系统学科里的进程状态&#xff08;运行、阻塞、挂起&#xff09;4.具体的Linux状态是如何维…

LinuxBasicsForHackers笔记 --常用Linux命令

在终端中修改用户密码命令&#xff1a;passwd Linux的文件系统是逻辑文件系统。 Linux基本命令 pwd – print working directory. 返回你当前所在目录结构中的位置。 whoami – 查看您当前登录的用户身份。 cd – change directory. 从终端更改目录。 cd / – 移动到根目录…

大数据实战项目_电商推荐系统

一、 项目介绍 HadoopSpark (Python)Scala SparkSQLSparkStreaming MongoDB Redis Kafka Flume ( SpringMVC vue) 1 项目介绍 1.1 项目系统架构 项目以推荐系统建设领域知名的经过修改过的中文亚马逊电商数据集作为依托&#xff0c;以某电商网站真实业务数据架构为基…

openGauss学习笔记-139 openGauss 数据库运维-例行维护-检查应用连接数

文章目录 openGauss学习笔记-139 openGauss 数据库运维-例行维护-检查应用连接数139.1 操作步骤139.2 异常处理 openGauss学习笔记-139 openGauss 数据库运维-例行维护-检查应用连接数 如果应用程序与数据库的连接数超过最大值&#xff0c;则新的连接无法建立。建议每天检查连…

淘宝商家店铺注册流程

如果本身已经有淘宝账号了&#xff0c;直接从第三步骤&#xff1a;创建店铺开始就可以了。一、注册淘宝账号、支付宝账号 首先,如果你有买家账号,是可以直接拿来开店的&#xff0c;不用单独在注册淘宝账号开店。 注意事项: 1:淘宝账号注册后,不能修改,如果会员名有写错情况&a…

【多线程】-- 10线程同步synchronized方法/块

多线程 6 线程同步 同步方法 由于我们可以通过private关键字来保证数据对象只能被方法访问&#xff0c;所以我们只需要针对方法提出一套机制&#xff0c;这套机制就是synchronized关键字&#xff0c;它包括以下两种用法&#xff1a; ​ synchronized方法和synchronized块 …

初始化 Clouder Manager 数据库报错Unable to find JDBC driver for database type: MySQL

CDH部署初始化 Clouder Manager 数据库报错。 解决方法&#xff1a; 把mysql驱动放到 /usr/share/java/目录下面(没有的新建&#xff09;&#xff0c;驱动名称也要修改为mysql-connector-java.jar 再次执行后成功&#xff1a; sudo /opt/cloudera/cm/schema/scm_prepare_data…

javaweb mybatis(手动jar包)

基础&#xff1a;https://blog.csdn.net/qq_67832732/article/details/134764134 条件查询 在映射文件的SQL配置中配置参数 使用parameterType来指定参数类型 使用#{参数名}来接收参数的值 parameterType"string" 表示sql语句需要一个参数&#xff0c;类型为字符…

串行口的工作原理及应用

前言 对最近串行口的学习进行一下总结。 参考链接 【51单片机】串口通信 - 知乎 (zhihu.com) LED数码管的静态显示与动态显示&#xff08;KeilProteus&#xff09;_proteus数码管显示-CSDN博客 定时器/计数器的应用-CSDN博客 74ls164_百度百科 (baidu.com) 74ls165中文资…

Kafka 的特点和优势

Apache Kafka 作为一款分布式流处理平台&#xff0c;以其独特的特点和卓越的优势成为实时数据处理领域的瑰宝。本文将深入研究 Kafka 的各项特点和优势&#xff0c;并通过详实的示例代码展示其在不同场景下的强大应用。 高吞吐量和水平扩展 Kafka 的设计注重高吞吐量和水平扩…

使用外部编辑器编辑执行MAXScript代码的方法

如何使用外部编辑器编辑执行MAXScript代码&#xff1f;这里我们要借助一个3dMax插件程序MXSCOM&#xff0c;MXSCOM允许从外部代码编辑器编辑和执行3ds Max MaxScript和Python文件。 2005年&#xff0c;Simon Feltman发布了第一个MXSCOM&#xff0c;这是一个小型的Visual Basic …

【Delphi】实现彩色日志显示框

目录 一、前言 二、实现方法 1. 第一步 2. 第二步 3. 第三步 三、主程序代码 四、下载 1. 可执行程序 2. 程序源代码 一、前言 在用Delphi做日常开发的时候&#xff0c;经常需要显示程序运行的日志&#xff0c;一般我们会使用TMemo&#xff0c;使用起来简单&#xff0c…

根据关键词写作文章的软件,根据标题写作文章的工具

在当今信息化时代&#xff0c;人工智能技术的飞速发展&#xff0c;智能AI写作工具逐渐成为文案创作者的得力助手。这些工具不仅能够根据标题迅速生成文章&#xff0c;而且在提高创作效率的同时&#xff0c;也为我们节省了大量时间和精力。 人工智能的基本原理&#xff1a;人工智…

Python遥感开发之快速判断TIF数据为空

Python遥感开发之快速判断TIF数据为空 前言&#xff1a;介绍一下如何使用python下的gdal读取tif数据的时候&#xff0c;快速判断该tif数据是否为空&#xff0c;如果为空的话就把当前的tif删掉。 如图所示&#xff0c;通过arcgis查看箭头指向的为空值。 仅通过文件的大小无法判…

java 工具类: CompareUtils(比较对象字段值变化)

一、前言 我们在工作中&#xff0c;可能会在日志中记录数据的变化情况或者在公共处理的数据增加一个日志页面&#xff0c;记录每次修改的变化。我们可以根据CompareUtils工具类比较数据前后发生了怎样的变化, 这样我们就可以知道数据做了哪些改变. 二、条件限制 在写这个通用…

【Leetcode题单】(01 数组篇)刷题关键点总结01【数组的遍历】

【Leetcode题单】&#xff08;01 数组篇&#xff09;刷题关键点总结01【数组的遍历】&#xff08;4题&#xff09; Easy数组的遍历485. 最大连续 1 的个数 Easy495. 提莫攻击 Easy414. 第三大的数 Easy628. 三个数的最大乘积 Easy 大家好&#xff0c;这里是新开的LeetCode刷题系…

【数组和函数实战: 斗地主游戏】

目录 1. 玩法说明 2. 分析和设计 3. 代码实现 4. 游戏演示1. 玩法说明 一副54张牌,3最小,两个王最大,其实是2,和上面一样从大到小排列 2. 分析和设计 2.1 分析和设计 常量和变量设计 一副牌有54张,有牌的数值和花色,可以分别用两个数组来存储,card为卡牌表示的数值,color为…