• 树莓派和PC的串口通信编程


    前言

    通信的内容有点多且杂,编程之前我们先来介绍下基础知识,通信术语扫盲。

    下面的内容多来自网上浏览汇总所得。

    通讯的基本概念

    实现信息传递所需的一切技术设备和传输媒质的合称为通信系统。
    在这里插入图片描述

    信源:消息的产生地,其作用是把各种消息转换成原始电信号,称之为消息信号或基带信号。电话机、电视摄像机和电传机、计算机等各种数字终端设备就是信源。
    发送设备:将信源和信道匹配起来,即将信源产生的消息信号变换为适合在信道中搬移的场合,调制是最常见的变换方式。对需要频谱搬移场合,调制是最常见的变换方式。对数字通信系统来说,发送设备常常又分为信源编码与信道编码。
    信道:传输信号的物理媒质。
    噪声源:是通信系统中各种设备以及信道中所固有的,为了分析方便,把噪声源视为各处噪声的集中表现而抽象加入到信道。
    接收设备:完成发送设备的反变换,即进行解调、译码、解码等等。它的任务是从带有干扰的接收信号中正确恢复出相应的原始基带信号来。
    信宿:传输信息的归宿点,其作用是将复原的原始信号转换成相应的信息。

    过程也比较易懂:
    信源(发送端)编辑好要发送的信息,通过发送设备进行对其数据处理,即将信源和信道进行匹配起来,对信源传输的数据经过编码的方式,变化成便于传输的信号形式。在传输到信息通道(可能在通过信道的时候会有干扰),在送到接受设备上进行解码、编译等工作,并传输到信宿(信息接受者)上。

    下面介绍4种概念:

    1、按数据的传送方式分为串行通讯与并行通讯
    2、按数据通讯方向分为全双工、半双工、单工通讯
    3、按数据通讯的同步方式分为同步通讯和异步通讯(是否使用时钟信号进行区分 )
    4、通讯速率:比特率和波特率

    串行通讯与并行通讯

    串行通讯:指设备之间通过少量数据信号线(一般是 8 根以下),地线以及控制信号线,按数据位形式一位一位地传输数据的通讯方式。

    并行通讯:指使用 8、16、32 及 64 根或更多的数据线进行传输的通讯方式,同时传输多个数据位的数据。

    两者比较:在数据传输速率相同时,并行效率更高,可以传输更多数据量;而串行通讯节省成本。并行传输对同步要求较高,且随着通讯速率的提高,信号干扰的问题会显著影响通讯性能。比较如下:

    特性串行通讯并行通讯
    通讯距离较远较近
    传输速率较慢较快
    抗干扰能力较强较弱
    成本较低较高

    全双工、半双工、单工通讯

    全双工:在同一时刻,两个设备间可以同时收发数据(普通电话、手机)

    半双工:两设备间可以收发数据,但不能在同一时刻进行(对讲机、收发报机)

    单工:在任何时刻只能进行一个方向的通讯,且固定一方为发送设备,一方为接收设备(广播、遥控、无线寻呼)

    在这里插入图片描述
    假定一对情侣吵架,在同一时间,男的说女的也可以反驳,信息交流是同时双向的,即全双工(我们打电话也是这样的);而男的说女的只能听不能反驳,同理,女的说男的也只能听不能反驳,同一时间只能允许一方信息交流,即半双工;男的一顿输出,女的反驳不了,信息交流是单向的,即单工。

    同步通讯和异步通讯

    同步通讯:收发设备双方会使用一根信号线表示时钟信号,在时钟信号的驱动下双方进行协调,同步数据。通讯中通常双方会统一规定在时钟信号的上升沿或下降沿对数据线进行采样。

    在这里插入图片描述

    异步通讯:不使用时钟信号进行数据同步,直接在数据信号中穿插一些同步用的信号位,或者把主体数据进行打包,以数据帧的格式传输数据,某些通讯中还需要双方约定数据的传输速率,以便更好地同步。

    在这里插入图片描述
    两者比较:在同步通讯中,数据信号所传输的内容绝大部分就是有效数据,而异步通讯中会包含有帧的各种标识符,所以同步通讯的效率更高,但是同步通讯双方的时钟允许误差较小,而异步通讯双方的时钟允许误差较大

    比特率和波特率

    比特率(Bitrate):每秒钟传输的二进制位数,单位为比特每秒(bit/s)。

    波特率(Baudrate):表示每秒钟传输了多少个码元

    以上摘自:https://blog.csdn.net/qq_43448818/article/details/124323762

    通讯协议的基本概念

    通信协议是指双方实体完成通信或服务所必须遵循的规则和约定。协议定义了数据单元使用的格式,信息单元应该包含的信息与含义,连接方式,信息发送和接收的时序,从而确保网络中数据顺利地传送到确定的地方。

    通信协议主要由以下三个要素组成:
    语法:即如何通信,包括数据的格式、编码和信号等级(电平的高低)等。
    语义:即通信内容,包括数据内容、含义以及控制信息等。
    定时规则(时序):即何时通信,明确通信的顺序、速率匹配和排序。

    物理外设规定我们是肢体交流还是嘴巴交流,那么协议就是规定我们是说中文还是英文

    常见串口协议有:IIC通信协议、SPI通信协议、 UART通信协议、CAN通信协议

    串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备的RXD接口。在串口通讯的协议层中,规定了数据包的内容,它由起始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。

    在这里插入图片描述

    数据信号传输补充概念

    1. 波特率
      USART的全称是通(U)用同步(S)异(A)步收®发(T)器,每个字母都有它对应的含义;不过本次学习的是串口异步通讯,因为同步通讯是需要时钟信号来进行同步的,但我使用的串口线没有时钟信号;因此两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码。常见的波特率为4800、9600、115200等。
    2. 通讯的起始和停止信号
      串口通讯的一个数据包从起始信号开始,直到停止信号结束,数据包的起始信号有一个逻辑0的数据位表示,而数据包的停止位可由0.5、1、1.5或2个逻辑1的数据位表示,只要双方约定一致即可。
    3. 有效数据
      在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度通常是8位。
    4. 数据校验
      在有效数据之后,有一个可选的数据校验位;由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程中加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0校验(space)、1校验(mark)以及无校验(noparity)。
    奇校验要求有效数据和校验位中"1"的个数为奇数 ,比如一个8位长的有效数据为:01101001,此时总共有4个"1",为达到奇校验效果,校验位为"1" ,最后传输的数据是将8位的有效数据加上1位的校验位总共9位
    偶校验偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数
    0校验不管有效数据中的内容是什么,校验位总为“0”
    1校验校验位总为“1”
    无校验在无校验的情况下,数据包中不含校验位

    以上来自:https://blog.csdn.net/Chen_qi_hai/article/details/96473076?spm=1001.2101.3001.6650.9&depth_1-utm_relevant_index=12

    编程实现

    那么介绍完基础概念之后,我们来编程实现树莓派和PC的串口通信。。

    demo1示例

    #include <wiringSerial.h>
    #include <wiringPi.h>
    #include <stdio.h>
    
    int main(){
            int fd;// //Linux 的思想是:将一切IO设备都看做文件,fd就是代表串口抽象出来的文件
            fd = serialOpen("/dev/ttyAMA0",9600);
    
            while(serialDataAvail(fd) != -1){
                    serialPutchar(fd,'s');
                    serialPuts(fd,"sxh\r\n");
                    delayMicroseconds(1000000);
            }
            serialClose(fd);
            return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    说明下:https://www.cnblogs.com/lulipro/p/5992172.html这篇文章里面有wiringPi的所有api哦

    运行结果:

    在这里插入图片描述

    demo2示例

    #include <wiringSerial.h>
    #include <wiringPi.h>
    #include <stdio.h>
    
    int main(){
            int fd;
            int cmd;
            fd = serialOpen("/dev/ttyAMA0",9600);
    
            while(serialDataAvail(fd) != -1){
                    cmd = serialGetchar(fd);
                    if(cmd == '1'){
                            serialPuts(fd,"i am one\r\n");
                    }
                    if(cmd == '2'){
                            serialPuts(fd,"i am two\r\n");
                    }
                    if(cmd == '3'){
                            serialPuts(fd,"i am three\r\n");
                    }
                    printf("get data:%d\r\n",cmd);
            }
            serialClose(fd);
            return 0;
    }
    
    • 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

    运行结果:

    在这里插入图片描述

  • 相关阅读:
    WMS仓库信息系统仓库信息Service模块
    部署zookeeper集群
    【JavaWeb】会话 Session
    Python基础_面向对象
    React Hooks之useState
    爬虫 — App 爬虫(一)
    SpringBoot整合knife4j3.0.3
    uCOSIII实时操作系统 六 内部任务(空闲函数)
    【Linux】Ubuntu 压缩与解压缩
    Spring Boot项目微信云托管入门部署
  • 原文地址:https://blog.csdn.net/qq_44333320/article/details/125504693