STM32串口通信教程及示例

STM32的串口通信

数据通信的基础概念

数据通信的分类

#mermaid-svg-2wvhBhssxjthy0rn {font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-2wvhBhssxjthy0rn .error-icon{fill:#552222;}#mermaid-svg-2wvhBhssxjthy0rn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2wvhBhssxjthy0rn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-2wvhBhssxjthy0rn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2wvhBhssxjthy0rn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2wvhBhssxjthy0rn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2wvhBhssxjthy0rn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2wvhBhssxjthy0rn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2wvhBhssxjthy0rn .marker.cross{stroke:#333333;}#mermaid-svg-2wvhBhssxjthy0rn svg{font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2wvhBhssxjthy0rn .label{font-family:”trebuchet ms”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-2wvhBhssxjthy0rn .cluster-label text{fill:#333;}#mermaid-svg-2wvhBhssxjthy0rn .cluster-label span{color:#333;}#mermaid-svg-2wvhBhssxjthy0rn .label text,#mermaid-svg-2wvhBhssxjthy0rn span{fill:#333;color:#333;}#mermaid-svg-2wvhBhssxjthy0rn .node rect,#mermaid-svg-2wvhBhssxjthy0rn .node circle,#mermaid-svg-2wvhBhssxjthy0rn .node ellipse,#mermaid-svg-2wvhBhssxjthy0rn .node polygon,#mermaid-svg-2wvhBhssxjthy0rn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2wvhBhssxjthy0rn .node .label{text-align:center;}#mermaid-svg-2wvhBhssxjthy0rn .node.clickable{cursor:pointer;}#mermaid-svg-2wvhBhssxjthy0rn .arrowheadPath{fill:#333333;}#mermaid-svg-2wvhBhssxjthy0rn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2wvhBhssxjthy0rn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2wvhBhssxjthy0rn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-2wvhBhssxjthy0rn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-2wvhBhssxjthy0rn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2wvhBhssxjthy0rn .cluster text{fill:#333;}#mermaid-svg-2wvhBhssxjthy0rn .cluster span{color:#333;}#mermaid-svg-2wvhBhssxjthy0rn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2wvhBhssxjthy0rn :root{–mermaid-font-family:”trebuchet ms”,verdana,arial,sans-serif;}

数据通信

按通信方式分类

串行通信

并行通信

按数据传输方向分类

单工通信

半双工通信

全双工通信

按数据同步方式分类

同步通信

异步通信

串行/并行通信

串行与并行的比较

解释:因为串行的数据传输是单线的而并行有多条线,多条线传输电信号的过程中会相互干扰,所以并行通信的抗干扰能力更弱。

单工/半双工/全双工通信
  • 单工通信:数据只能沿一个方向传输

  • 半双工通信:数据可以沿两个方向传输,但需要分时进行(两方向,同线,不同时)

  • 全双工通信:数据可以同时进行双向传输
  • 同步/异步通信
  • 同步通信:共用同一时钟信号

  • 异步通信:没有时钟信号,通过在数据信号中加入起始位和停止位等一些同步信号

  • 波特率

  • 比特率:每秒钟传送的比特数,单位bit/s
  • 波特率:每秒钟传送的码元数,单位Baud
  • 比特率 = 波特率 * [log2 M ],(log2 M取不小于log2 M的整数。M表示每个码元承载的信息量)

    二进制系统中,波特率数值上等于比特率

    补充——码元

    码元(Symbol)是数字通信中的基本单位,它代表着一种离散的信号状态。在数字通信中,信息通常以一系列离散的码元进行传输和表示。

    码元可以是二进制的(0和1),也可以是多进制的(例如四进制、八进制等)。每个码元代表着一定的信息,例如一个二进制码元可以表示一个比特(bit),而一个四进制码元可以表示两个比特。

    举例

    用二进制表示两次抛硬币的结果则有00,01,10,11四种这个结果就是一个码元,在此,一个码元代表2位二进制。

    设其波特率为x

    比特率 = 波特率 × 每个码元所表示的比特数

    所以其比特率就为x*2

    相同的,若跑三次硬币,以三次结果为波特率,000,001,010,011,100,101,110,111,一个码元包含8种信息,即3位比特数,所以比特率=x*3.

    常见的串行通信接口

    =img-4GGJwYEr-1707208040434)

    数据帧

  • 数据帧:数据帧(Data Frame)是在计算机网络和通信领域中使用的一种数据传输单位。它是将数据分割成一系列固定长度的单元,并添加了一些控制信息和标识符,以便在网络中正确传输和识别数据。
  • 串口的数据帧格式

    空闲


    起始位

    起始位:表示数据帧的开始,实际使用1位低电平表示起始位

    数据位

    用于传输数据

    低电平表示0,高电平表示1

    8~9位

    LSP First (Least Significant Bit First)先传最低有效位

    校验位

    校验位:为了检验数据传输是否出错而设立的比特位

    校验位和数据位的关系

    奇偶校验规则
    graph LR
    A[奇偶校验(查1的个数)]-->B[奇校验]
    B-->B1[控制校验位为0/1,使数据位和校验位1的总数位奇数]
    A-->C[偶校验]
    C-->C1[控制校验位为0/1,使数据位和校验位1的总数为偶数]
    

    停止位

    停止位:表示数据帧的结束,高电平,长度可以是0.5, 1, 1.5, 2

    数据发送

    单个数据发送

    单个数据发送:在单个数据发送中,每个数据单元(如字符或字节)都被独立地发送。发送端将一个数据单元封装成一个数据帧,并通过物理介质将其发送给接收端。接收端收到一个数据单元后,进行处理和分析,然后等待下一个数据单元的到达。

    单个数据发送适用于一次性传输独立的数据单元,每个数据单元之间可能存在较长的时间间隔

    连续发送

    连续发送:在连续发送中,多个数据单元被连续地发送。发送端将多个数据单元组合成一个数据流,并通过物理介质连续地发送给接收端。接收端在接收到数据流后,进行解析和处理,将连续的数据单元还原出来。

    连续发送适用于需要高速率传输或实时性要求较高的场景。

    e.g.

    发送Hello

    8位数据位,无校验, 1位停止位
    H – 0x48 (0100 1000) e – 0x65(0110 0101) l – 0x6c(0110 1010) o – 0x6f (0110 1111)

    硬件流控

    流控的概念

    数据流控(Flow Control)是在数据通信中使用的一种机制,用于控制发送方和接收方之间的数据传输速率,以避免数据丢失或过载。

    产生意义:

    在数据通信中,发送方和接收方可能存在传输速率不匹配的情况。如果发送方连续地向接收方发送数据,而接收方的处理能力有限,可能导致接收方无法及时处理所有的数据,从而造成数据丢失或缓冲区溢出。为了解决这个问题,数据流控机制被引入。

    就是因收发速度不同,为防止发送端速度过快,接收端未来得及接受数据就被新数据覆盖而导致的数据丢失问题。于是有了“数据流控”来控制发送端的传输速度。

    实现流控的方法

    1. 停止-等待流控:发送方在发送完一个数据包后,等待接收方的确认信号,然后再发送下一个数据包。这种方式可以确保接收方有足够的时间来处理接收到的数据,但会导致发送方的利用率较低。

      以听写为例(左为无流控,右为流控结果)

    2. 滑动窗口流控:发送方和接收方之间维护一个滑动窗口,窗口的大小表示允许发送的未确认数据包数量。发送方根据窗口大小来发送数据包,接收方根据窗口大小来确认已接收的数据包。通过动态调整滑动窗口的大小,可以实现发送方和接收方之间的数据传输速率匹配。

      举例

    3. 缓冲区管理:在接收方使用缓冲区来存储接收到的数据,以便在处理能力不足时,暂时存储数据而不丢失。通过合理管理缓冲区的大小和数据处理能力,可以实现数据流控。

      举例

      假设你是一位餐厅服务员,负责将菜品送到客人桌上。餐厅的厨房有一个10个盘子的缓冲区,你可以将菜品放到缓冲区中,然后再将其送到客人桌上。然而,客人的用餐速度有限,他们只能及时吃完3个盘子的菜品。当缓冲区中的盘子满时,你会通知厨房停止制作菜品,直到客人吃完一些菜品,腾出空间来。

    串口流控的工作原理

    串口(以RS-232为例)

  • 串口:串行通信接口:指按位发送和接收的接口。如:RS-232/422/485等

  • RS-232接口(DB9)

  • 数据:

    TXD(pin 3):串口数据输出

    RXD(pin 2):串口数据输入

  • 握手:

    RTS(pin 7):请求发送

    CTS(pin 8):清除发送

    DSR(pin 6):数据发送就绪

    DCD(pin 1):数据载波检测

    DTR(pin 4):数据终端就绪

  • 地线:

    GND(pin 5):信号地

  • 其他:

    RI(pin 9):振铃指示

  • RS-232电平与COMS/TTL电平对比

    RS-232电平 COMS电平(3.3V) TTL电平(5V)
    逻辑1:-15V ~ -3V 逻辑1:3.3V 逻辑1:5V
    逻辑0:+3V ~ +15V 逻辑0:0V 逻辑0:0V

    由此观之,COMS/TTL电平不能与RS-232电平直接交换信息

    设备间的RS-232通信示意图

    STM串口与电脑USB口通信示意图

    S3-232异步通信协议

  • 启动位:必须占1个位长,保持逻辑0电平
  • 有效数据位:可选5、6、7、8、9个位长,LSB(最小数据位,在途中表示位位0)在前,MSB(最大数据位,在图中表示为位7)在后
  • 校验位:可选占1个位长,也可以没有该位
  • 停止位:必须有,可选占0.5、1、1.5、2个位长,保持逻辑1电平
  • STM32的USART

    USART : Universal synchronous asynchronous receiver transmitter,通用同步异步收发器

    UART : Universal asynchronous receiver transmitter,通用异步收发器

  • USART/UART都可以与外部设备进行全双工异步通信

  • USART,我们常用的也是异步通信

  • STM32的主要特征

    1,全双工异步通信

    2,单线半双工通信

    3,单独的发送器和接收器使能位

    4,可配置使用DMA的多缓冲器通信

    5, 多个带标志的中断源

    参考:STM32xxxx参考手册(中文版).pdf USART相关章节

    参考:STM32F103ZET6(中文版).pdf

    STM32F1USART框图

    **注意:框图中灰色的部分(即发送数据寄存器、发送移位寄存器、接接收数据寄存器、收移位寄存器)都是不可直接读取或写入数据的。**要获取输入的数据,必须通过接收数据寄存器将数据传输到数据寄存器中再读取。

    现大致将框图分为3部分来讲解

  • 发送接收数据的流程
  • 相关寄存器的作用
  • 设置波特率
  • 发送/接收数据的流程

    由图可知,TX和RX引脚用作数据的输入与输出。

    当传输数据时,外部输入设备输入串行数据至RX引脚,通过编解码模块再到接收移位寄存器,再传输到接收数据寄存器,最后到CPU处理。

    发送数据时通过CPU发送数据至发送数据寄存器,再到发送移位寄存器最后通过编解码模块传输到TX引脚,输出到外部设备。

    相关寄存器的作用
  • GTPR 寄存器:用于设置 USART 的守护时间和预分频器值。守护时间是指在停止位和下一个起始位之间的空闲时间。预分频器用于设置通信时钟的分频比,以确定波特率的精确值。

  • CR1 寄存器用于配置 USART 的工作模式和通信参数。其中可能包括以下功能:

    – 波特率设置:用于设置 USART 的波特率,包括整数部分和小数部分。

    – 数据位数:用于选择发送和接收数据时使用的数据位数,如 8 位、9 位等。

    – 奇偶校验:用于选择奇偶校验模式,或者禁用校验。

    – 发送和接收使能:用于启用或禁用发送和接收功能

  • CR2 寄存器用于配置 USART 的一些附加参数。其中可能包括以下功能:

    – 停止位设置:用于选择发送和接收数据时使用的停止位的数量。

    – 数据极性:用于定义数据的电平极性,可以选择正常或反转极性。

    – 硬件流控制:用于启用或禁用硬件流控制功能,如 RTS/CTS 流控制。

  • CR3 寄存器用于配置 USART 的一些其他功能。其中可能包括以下功能:

    – DMA 控制:用于启用或禁用 DMA(直接内存访问)控制,以实现无需 CPU 干预的数据传输。

    – 半双工模式:用于配置 USART 为半双工通信模式。

    – 错误中断使能:用于启用或禁用错误中断,以在发生错误时触发相应的中断处理程序。

  • 设置波特率(USART1为例)

    (STM32F1USART框图中词部分用于波特率的设置)

    计算

    (F1)波特率计算公式:baud=“fck” /(16∗USARTDIV)

    其中"fck"是串口的时钟,如:USART1的时钟是PCLK2,其他串口都是PCLK1

    USARTDIV表示USART波特率分频寄存器的值

    例如

    波特率为115200时:

    115200=72000000/(16*USARTDIV)

    //通过查询STM32参考手册可知USART1的时钟最大频数是72M,所以fck填入72*10**6

    得USARTDIV=39.0625

    将数据写入到寄存器中

    波特比率寄存器

    把USARTDIV的整数部分写入位[15:4], USARTDIV的小数部分写入[3:0]

    uint16_t mantissa; 
    uint16_t fraction; 
    mantissa=39; 
    fraction=0.0625*16+0.5=0x01;          /* USARTDIV = DIV_Mantissa + (DIV_Fraction/16) */
    USART1->BRR = (mantissa << 4) + fraction;
    
    

    说明

  • 代表写入数据的整数部分39
  • mantissa << 4是因为写入数据是整数部分占[15:4],右边的[3:0]要留给小数部分所以整体左移
  • fraction=0.0625*16+0.5=0x01;
  • 其中*16的功能与<<4相同。因为是小数但填入后是二进制的形式不左移的话超出范围且[3:0]空了所以要左移
  • +0.5的目的是实现四舍五入类似Python中int(x+0.5)
  • 至此波特率的设置的理论就基本完成了。为了更加方便接下来讲解波特率设置通用公式的推演。

    波特率设置通用公式推演

    ion=0.062516+0.5=0x01; / USARTDIV = DIV_Mantissa + (DIV_Fraction/16) */
    USART1->BRR = (mantissa << 4) + fraction;

    
    > 说明
    >
    > + 代表写入数据的整数部分39
    > + mantissa << 4是因为写入数据是整数部分占[15:4],右边的[3:0]要留给小数部分所以整体左移
    > + fraction=0.0625*16+0.5=0x01; 
    >   + 其中*16的功能与<<4相同。因为是小数但填入后是二进制的形式不左移的话超出范围且[3:0]空了所以要左移
    >   + +0.5的目的是实现四舍五入类似Python中int(x+0.5)
    
    
    
    
    
    
    
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32串口通信教程及示例

    发表评论