嵌入式USART
USART 能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标准 NRZ 异步串 行数据格式的要求。USART 通过小数波特率发生器实现了多种波特率。USART 不仅支持同步单向通信和半双工单线通信,以及 LIN(局域互连网络)、智能卡 协 议、IrDA(红外线数据协会)SIR ENDEC 规范和调制解调器操作 (CTS/RTS),还支持多 处 理器通信。通过配置多个缓冲区使用 DMA(
通信
- 什么是通信
需要发送端和接收端
信息之间的交互
- 通信分类
按时钟信号:
同步通信:通信双方共用同一个时钟信号,发送数据的时候会出现阻塞状态,需要等待数据传输完毕,程序才会执行到下一行
异步通信:通信双方各自有自己独立的时钟系统,大家需要约定好通信速度(相同的波特率)发送数据的时候没有阻塞状态,执行发送数据语句后直接执行下一行语句
按通信方式:
串行通信:指的是同一时刻只能收或发一个bit位信息。因此只用1根信号线即可,以bit为单位传输,占用引脚资源相对较少,但速度相对较慢
并行通信:多跟数据线同时发送信号,同一时刻可以收或发多个bit位的信息,需要多根信号线才行,一般以字节为单位传输,速度相对较快但,占用引脚资源多
按通信方向:
单工: 只能执行收或者执行发; 一根信号线 例:收音机
半双工:可以收可以发但不能同时收发;一根信号线 例:对讲机
全双工:可以收可以发且可以同时收发; 两根信号线 例:手机
电平信号与差分信号:1.电平信号:电平信号有一根是参考电平线,信号线的信号值有信号线和参考电平线之间的电压差决定;
2.差分信号:差分信号没有参考电平线,传输一路数据需要两根信号线,信号线的信号值由两根信号线的电压差决定。
区别:
(1)信号值的表示不同:电平信号的信号值是信号线和参考电平线的电压差决定;差分信号的信息值是由两条信号线的电压差决定;
(2)传输相同路数的信号,电平信号用的数据线根数比差分信号少。比如传输3路信号,电平信号需要1根参考电平+3根数据线;而差分信号需要2x3=6根数据线;
(3)现在通信大部分是差分信号,因为差分信号的抗干扰性更强,可以在更短的周期传输一个数据。双绞线
RS232
RS485
RS422
电气特性
电平信号(抗干扰性弱)
差分信号(抗干扰性强)
差分信号(抗干扰性强)
逻辑电平范围
(±3V~±15V)
±(2~6)V
数据传输方向
全双工
半双工
全双工
对应关系
仅支持点对点
支持多点通信
支持一点发多点收
引脚
TXD /RXD / GND等
双绞线差分对
四线制
TXD+ TXD-
RXD+ RXD-
使用场景
早期广泛用于计算机与外设(如调制解调器、打印机)的短距离数据传输
高速、长距离、多点通信
成本低,节点数少
UART
1.简介
USART 能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标准 NRZ 异步串 行数据格式的要求。USART 通过小数波特率发生器实现了多种波特率。
USART 不仅支持同步单向通信和半双工单线通信,以及 LIN(局域互连网络)、智能卡 协 议、IrDA(红外线数据协会)SIR ENDEC 规范和调制解调器操作 (CTS/RTS),还支持多 处 理器通信。
通过配置多个缓冲区使用 DMA(直接存储器访问)可实现高速数据通信。
USART 通用同步/异步收发器 支持同步/异步通信、全双工、串行(TX和RX各一条线)
UART 通用异步收发器 没有时钟线,只支持异步通信、全双工、串行
注意:我们在使用时,往往使用的是串口的异步通信,即UART,对于同步通信还是SPI和IIC使用的更多
2.结构框图

流程:
发送:
CPU将数据放到发送数据寄存器TDR(软件完成)
↓
硬件将TDR中的数据复制到移位寄存器(硬件完成)
↓
移位寄存器将数据逐位发送到TX引脚(硬件完成)
接收:
外部数据到达RX引脚
↓
移位寄存器逐位的收集数据,等数据完整后将数据送到RDR寄存器
↓
CPU从RDR取走数据
3.通信协议
数据帧组成:起始位 数据位 (校验位) 停止位


4.相关寄存器
4.1数据接收寄存器

4.2数据发送寄存器

4.3中断和状态寄存器

4.4波特率寄存器
决定通信速度(bit/s)

5.重定向
注意:使用标准库时,记得勾选以下选项

printf重定向:
printf函数底层调用的是fputc函数,fputs是将要发送的数据写入到标准输出流stdout
因此如果想让printf将数据输出到串口,需要重写fputc
int fputc(int /*c*/, FILE * /*stream*/)
#include "stdio.h" int fputc(int ch,FILE *p) { while(!(USART1->ISR &(1<<7))){} //等待发送寄存器空 //ISR的第七位是1 ,说明发送寄存器是空,这个时候再去写入要发送的数据 //当发送寄存器是空,跳出循环,把数据放好发送数据寄存器里面 USART1->TDR = ch; return ch; }
scanf重定向:
重写fgetc函数
#include "stdio.h" int fgetc(FILE *p) { while(!(USART1->ISR &(1<<5))){} //等待接收寄存器有数据 //ISR的第五位是1 ,说明接受寄存器有数据,这个时候再去CPU可以拿取数据 //当发送寄存器是空,跳出循环,把数据放好发送数据寄存器里面 return USART1->RDR; }
6.相关HAL库函数
串口发送数据函数:
功能:通过串口发送数据
/*
参数1:句柄,判断是使用哪个串口外设(U5系列有5个串口外设)
参数2:要发送数据的首地址
参数3:发送数据的大小(多少字节)
参数4:超时时间,即要发送多长时间,单位为ms(一般设为1秒)
返回值:发送状态
*/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
串口接收数据函数:
功能:通过串口接收数据
/*
参数1:句柄,判断是使用哪个串口外设(U5系列有5个串口外设)
参数2:接收数据要存放在哪(一个uint8_t类型的数组首地址)
参数3:接收数据的大小(多少字节)
参数4:超时时间,即要接收多长时间,单位为ms (一般设为1秒)
返回值:接收状态
*/
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
注意:汉字一个字占2字节,keil使用UTF-8编码可能会有乱码的可能(UTF-8中中文是3字节),使用GBK(占2字节)不会

7.CubeMX配置

8.串口实验
见day2_UART文件夹
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐






所有评论(0)