UART和USART
UART:universal asynchronous receiver and transmitter 通用异步收发器
USART:universal synchronous asynchronous receiver and transmitter 通用同步和异步收发器
UART:一般只能用于异步串行通信。
USART:既可以用于同步串行通讯,也能用于异步串行通讯。
通信方式
- 串行通信:
- 传输原理:数据按位顺序传输
- 优点:占用引脚资源少
- 缺点:速度相对较慢
- 并行通信:
- 传输原理:数据各个为同时传输
- 优点:速度快
- 缺点:占用引脚资源多
传送模式
- 单工模式
- 半双工模式
- 全工模式
同步和异步
- 同步:发送方发出数据后,等接收方回响应以后才发下一个数据包的通讯方式
- 异步:发送方发出数据后,不等接收方回响应,接着发送下个数据包的通讯方式
同步是阻塞模式,异步是非阻塞模式
通信标准 | 通信方式 | 通信方向 |
UART | 异步通信 | 全双工 |
SPI | 同步通信 | 全双工 |
I2C | 同步通信 | 半双工 |
开发板的串口资源
引脚编号 | 引脚名称 | 默认复用功能 |
12 | PA2 | USART2_TX |
13 | PA3 | USART2_RX |
21 | PB10 | USART3_TX |
22 | PB11 | USART3_RX |
30 | PA9 | USART1_TX |
31 | PA10 | USART1_RX |
串口1用于下载程序,串口2用于与WIFI等的连接。
外设GPIO的USART配置
串口通信的配置流程
- 串口、GPIO时钟使能
RCC_APB2PeriphClockCmd();
- GPIO端口模式设置
CPIO_Init();
- 串口参数初始化
USART_Init();
- 开启中断并且初始化NVIC
NVIC_Init();
USART_ITConfig();
- 使能串口
USART_Cmd();
- 编写中断处理函数
USARTx_IRQHandler();
串口数据收发:
void USART_SendData();
uint16_t USART_ReceiveData();
串口传输状态:
//得到标志位状态
//参数:哪个串口,变量
//返回标志位的状态:0或1
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
//清除标志位
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
//获取中断的状态,判断中断是否打开
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
//清除与中断相关的标志位
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
- 不论接收还是发送,都是通过两个寄存器(发送数据寄存器TDR、接收数据寄存器RDR)
- 接受和发送使用的都是同个寄存器(数据寄存器DR)
- 整个过程是由CPU或者DMA处理
相关寄存器
状态寄存器(USART_SR)
TXE:发送数据寄存器空(Transmit data register empty),与发送数据寄存器相关
TC:发送完成(Transmission complete),与发送移位寄存器相关
RXNE:读数据寄存器非空(Read data register not empty)
TEX和TC的复位值为1,RXNE的复位值为0!
小实验
单片机通过串口1发送一个字符到电脑上
//my_usart1.h
#define USART1_GPIO_PIN_TX GPIO_Pin_9
#define USART1_GPIO_PIN_RX GPIO_Pin_10
#define USART1_GPIO_PORT GPIOA
void My_USART1(void);
void My_USART1(void){
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART1_InitStrue;
//1. 串口、GPIO时钟使能
RCC_APB2PeriphClockCmd(RCC_APB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//2.GPIO端口模式设置
GPIO_InitStructure.GPIO_Pin = USART1_GPIO_PIN_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = USART1_GPIO_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//3. 串口参数初始化
USART1_InitStrue.USART_BaudRate = 9600; //波特率
USART1_InitStrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流动控制,一般选择无
USART1_InitStrue.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //模式
USART1_InitStrue.USART_Parity = USART_Parity_No; //
USART1_InitStrue.USART_StopBits = 8; //发送位数
USART1_InitStrue.USART_WordLength = USART_WordLength_8b; //长度
USART_Init(USART1,&USART1_InitStrue);
//4. 开启中断并且初始化NVIC
//本次没有使用中断,暂时不需要
//5. 使能串口
USART_Cmd(USART1,ENABLE);
//6. 编写中断处理函数
//本次没有使用中断,暂时不需要
}
在主函数中调用
int main(void){
My_USART1();
USART_SendData(USART1,'H');
while(1){}
}