嵌入式常用通信协议 #UART

一、概述

        Universal Asynchronous Receiver/Transmitter,UART是一种通用、异步串行通信总线,其有两根信号线,可实现全双工的发送和接收,一般用于点对点的、主机对从机间的通信。

         两根信号线分别为发送线(TXD)和接受线(RXD),TXD用于给别人发送数据,RXD用于接收别人发来的数据。

        通常在使用串口时,需要将发送者和接收者的地线(GND)接在一起,这将会使两者的参考电平一致,利于数据发送的稳定。

                  

二、UART的数据帧格式与波特率

        UART的一帧数据有11位(按照配置而有所变化),当数据线(TXD或RXD)的电平产生下降沿时,代表起始位,此时开始通信,按照先发低位后发高位的方式依次发送8位(数据位可配置为5~8位)数据位后,再根据配置发送一位校验位(校验位可配置为奇偶校验或者无校验位),最后再产生一个上升沿作为停止位,便是一帧数据。

        总的来说,UART的数据帧就只包括:起始位、数据位、校验位、停止位。当有数据要传输时,按照这种格式来搭建数据帧,当数据线空闲时,默认为高电平,以便下次发送起始位。

        数据帧格式已经很清楚了,但是试想当这样一种情况发生时会如何处理:

这两种情况在接收方看来都是一样的,都是先高电平后低电平,没法区分是1100还是10又或者是11110000,为解决这种问题,UART引入波特率的概念,波特率的意思是一秒内能发送多少位,比如说当波特率为9600时,发送者和接收者达成协议,都认为数据线上一秒钟能读取9600位的信号,将一秒钟9600等分,便可以精确的计算出每位信号持续的时间,于是判断高电平或低电平持续多少时间,就能够分辨出持续的高电平中到底有几位数据,通过这种最古朴的掐时间方式,上图的问题就解决了。

        常见的波特率取值通常是2的整数次幂,以确保波特率发生器能够从微控制器或计算机系统的主时钟频率进行简单的分频。如9600、115200、1000000等。

        波特率是凭借单片机中的时钟频率来产生的,有时候时钟频率会产生误差,导致一秒内不一定读取了9600次数据位,在串行通信中,一位错,就位位错,这将会导致非常严重的数据错误,但是UART使用起始位和停止位来隔断数据位,即使存在时钟频率的误差,接收者也可以很清楚的接收并处理一帧数据,再加上一帧数据不会有太多位,时钟频率的误差就被解决了。试想如果一秒内的9600位数据仅有第一位的起始位和最后的停止位,如此长的数据,不可避免的会严重受到时钟频率误差的影响。

三、UART的特点

  • 异步性: UART是一种异步通信协议,发送端和接收端的时钟不需要保持严格的同步。相反,它们通过在数据帧中插入起始位和停止位来同步数据传输。这使得UART在速率不一致或不固定的情况下能够有效地进行数据传输。

  • 简单性: 相对于其他串行通信协议(如SPI或I2C),UART具有相对较简单的硬件要求和协议规范。它通常只需要少量的硬件逻辑和少量的控制信号。

  • 全双工或半双工: UART可以支持全双工或半双工通信。在全双工模式下,发送器和接收器可以同时发送和接收数据。在半双工模式下,数据传输是双向的,但每次只能进行其中一种操作(发送或接收)。

  • 波特率灵活性: 波特率是UART通信中非常重要的参数,它决定了数据传输的速率。UART通常可以灵活地支持多种波特率,使得它可以适应不同应用中的不同速率要求。

  • 可靠性: 虽然UART在速率较慢的情况下使用,但它具有良好的可靠性。由于其简单的硬件实现和异步性质,UART通常能够在不同环境条件下稳定地进行数据传输。

三、STM32F1的UART

        1.USART框架

        STM32F1支持USART和UART,是全双工的异步通信,波特率最高可达4.5M bit/s,支持数据位长度为8位或9位,支持1或2个停止位。

        上图左边的引脚:TX就是发送端,RX就是接收端,SW_RX只用于单线模式或智能卡模式,IRDA_OUT和IRDA_IN是IRDA红外通信协议相关的,右侧的SCLK是时钟引脚,在同步模式的时候会用到。

        STM32F1的USART有两个数据寄存器:发送数据寄存器(只写)和接受数据寄存器(只读),在物理上存在着两个寄存器,但是在软件上只有一个数据寄存器,读数据或写数据都被简化为了同一个数据寄存器。

        接受数据时,数据信号从RX脚进入接收移位寄存器,接收完一帧数据后,接收移位寄存器会迅速将数据送入接受数据寄存器(RDR)中,然后标志位RXE置高,如果打开了串口接收中断,则会触发中断信号,当cpu或dma将数据寄存器(RDR)中的数据读走后,数据寄存器(RDR)会清零并将标志位RXE置低,以等待下一次数据进入。

        发送数据时,cpu或dma向发送数据寄存器(TDR)中写入数据,此时标志位TXE会置高,发送移位寄存器会迅速将数据接过来并以低位到高位的顺序依次将数据发送到TX引脚上,当数据从发送数据寄存器(TDR)全部移动到发送移位寄存器后,标志位TXE就置低,以等待下次发送数据的输入。

        硬件数据流控:

                简单的说,硬件数据流控是为了确保数据准确被接收,减少数据丢失概率的一种方法。        

                在接收数据时,如果对方一直不间断发数据过来,我们处理数据的速度跟不上接受数据的速度,就会导致一些数据被覆盖,而如果采用硬件数据流控的模式,在完全处理此次接受的数据前,发送方是不被允许发送数据的,只有在我处理完数据后,nRTS置低,发送方才能再次发送数据给我。发送数据时同理,只有在nCTS为低电平时,发送者才能发送数据。

                硬件数据流控引入了额外的两根线(nRTS与nCTS)当作标志位来指挥收发数据。

        

 

         2.寄存器

        (1)状态寄存器(USART_SR)

 

         (2)数据寄存器(USART_DR)

         (3)波特比率寄存器(USART_BRR)

         (4)控制寄存器 1(USART_CR1)

 

                 (5)控制寄存器 2(USART_CR2)

         (6)控制寄存器 3(USART_CR3)

         (6)保护时间和预分频寄存器(USART_GTPR)

         (7)USART寄存器地址映象

四、应用(STM32F1)

        0.USART初始化

1.开启USART及TX与RX脚GPIO的时钟

2.配置TX脚与RX脚为推挽输出和浮空输入

3.配置波特率

4.配置控制寄存器

5.(可选)配置串口中断

#include "stm32f10x.h"

void USART1_Init(void);

int main(void) {
    USART1_Init();

    while(1) {
        // 主循环中可以进行其他操作
    }

    return 0;
}

void USART1_Init(void) {
    // 使能 USART1 时钟
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

    // 配置 USART1 引脚
    GPIOA->CRH |= GPIO_CRH_MODE9; // TX 引脚输出模式,最大速度 50MHz
    GPIOA->CRH |= GPIO_CRH_CNF9_1; // TX 引脚复用推挽输出

    GPIOA->CRH |= GPIO_CRH_CNF10_0; // RX 引脚输入模式

    // 配置波特率
    USART1->BRR = 0x271; // 波特率为 9600,对于 72MHz 的系统时钟

    // 配置 USART1 控制寄存器
    USART1->CR1 |= USART_CR1_UE; // 使能 USART1
    USART1->CR1 |= USART_CR1_TE; // 使能发送
    USART1->CR1 |= USART_CR1_RE; // 使能接收
}

        1.printf重定向

        2.RS232

        3.RS485

        4.自定义数据包

        

        5.使用USART操控SPI设备

        

  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值