STM32 串口与USART
1. 串口基础知识
1.1 串口简介
- 硬件传递数据的接口
- 硬件通讯按照各种协议传递信息
1.2 常见通讯接口对比
| 名称 | 引脚 | 双工 | 时钟 | 电平 | 设备 |
|---|---|---|---|---|---|
| USART | TX、RX | 全双工 | 异步 | 单端 | 点对点 |
| I2C | SCL、SDA | 半双工 | 同步 | 单端 | 多设备 |
| SPI | SCLK、MOSI、MISO、CS | 全双工 | 同步 | 单端 | 多设备 |
| CAN | CAN_H、CAN_L | 半双工 | 异步 | 差分 | 多设备 |
| USB | DP、DM | 半双工 | 异步 | 差分 | 点对点 |
1.3 串口连接
- 简单的串口通讯通过两个通信线连接(TX、RX)
- 单向通讯时,只需要单线就行
======================================================
2. 电平标准
2.1 常见电平标准
- TTL电平:+3.3V或+5V表示1,0V表示0
- RS232电平:-3~-15V表示1,+3~+15V表示0
- RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)
======================================================
3. 串口参数及时序
3.1 串口参数
- 波特率:串口通信的速率
- 起始位:标志一个数据帧的开始,固定为低电平
- 数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
- 校验位:用于数据验证,根据数据位计算得来
- 停止位:用于数据帧间隔,固定为高电平
3.2 时序说明
- 1帧共10位:起始位 + 8位数据位 + 停止位
- 1帧共11位:起始位 + 8位数据位 + 校验位 + 停止位
- 空闲状态:高电平
- 数据传输:低位(LSB)先行,高位(MSB)在后
======================================================
4. USART(通用同步/异步收发器)
4.1 基本信息
- 自带波特率生成器(分频器,计算得波特率)
- 计算公式:Fpclk2/1/(16×DIV)
- 时序配置:
- 数据位:8/9(如果8位,不开启校验位,如果9位,开启校验,为了方便8位1bit)
- 停止位:0.5/1/1.5/2
- 校验位:0/2n/2n+1
- 硬件资源:USART1(APB2), USART2, USART3
4.2 配置步骤
- 开启USART和GPIO的RCC时钟
- GPIO初始化
- 配置USART
- 配置中断
- 使能USART
4.3 配置代码示例
4.3.1 初始化配置
c
//开启GPIO和USART时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//配置RX/TX的GPIO
//TX——复用推挽输出
//RX——上拉输入
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置USART
*1.确定波特率
*2.选择无硬件流控制
*3.选择TX与RX均开启
*4.无校验位
*5.1个停止位
*6.8个数据位
*/
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
//配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//使能接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//使能USART
USART_Cmd(USART1, ENABLE);4.3.2 发送数据
c
void USART_SendByte(uint8_t byte)
{
USART_SendData(USART1, byte);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void USART_SendString(char *str)
{
while (*str != '\0')
{
USART_SendByte(*str);
str++;
}
}4.3.3 接收数据(中断方式)
c
uint8_t USART_ReceiveData;
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
USART_ReceiveData = USART_ReceiveData(USART1);
// 处理接收到的数据
USART_SendByte(USART_ReceiveData); // 回显
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}