基于STM32串口通信
一、串口简介
串口,也称为串行接口或串行通信接口(通常指COM接口),是一种采用串行通信方式的扩展接口。它实现了数据一位一位地顺序传送,具有通信线路简单、成本低但传送速度慢的特点。 只要一对传输线,串口就可以实现双向通信。以PC端和STM32为例,PC端通过USB转TTL可将信息传送到STM32,反过来也亦然。
PC端与STM32之间的串口通信图
串口通信数据:
串口发送数据长度图
通常为异步通信,一般没有SCLK。
1、 起始位(Start Bit):起始位为低电平时,告诉接收方数据传输即将开始,准备接收。 在通信开始时,发送端首先会发送一个起始位,它是一个逻辑0(低电平)的信号,用于同步发送和接收设备之间的时钟。接收端在检测到起始位后,会开始准备接收后续的数据位。
2、有效数据位(Data Bits):数据位是由一系列二进制值组成,用于传输或接收实际的数据。数据位的数量决定了可以传输的不同二进制值的数量,常见的有5位、6位、7位、8位,LSB在前,MSB在后。 数据位紧随起始位之后,包含了要传输的实际信息。
3、 校验位(Parity Bit):校验位用于验证数据的完整性,以确保传输过程中没有出现错误。常见的校验位选项有None(无校验位)、Odd(奇校验位)和Even(偶校验位)。在发送数据时,校验位会根据数据位中1的个数进行计算,并加入到数据中一起传输。接收端则会根据校验位的值进行校验,以判断数据是否存在错误。【一般采用无校验位】
4、停止位(Stop Bit):停止位是一个逻辑高电平(1),用于指示数据传输的结束。 当停止位出现时,接收端知道数据传输已经完成,并且可以开始处理接收到的数据。停止位位于数据位和校验位之后,它的作用是确保接收端有足够的时间来识别数据帧的结束,并为下一个数据帧的到来做好准备。
STM32串口通信简介:
1、 全双工通信:USART支持全双工通信,即数据可以在两个方向上同时传输(A→B且B→A)。这使得USART能够满足许多需要双向通信的应用场景。
2、同步与异步传输:尽管USART的“S”代表同步,但在实际应用中,USART更常用于异步通信。 然而,它也支持同步通信模式,只是这种模式通常用于兼容其他协议或特殊模式,并且两个USART设备不能通过同步模式进行直接通信。
3、 波特率发生器:USART自带波特率发生器,最高可达4.5Mbits/s,可以根据需要配置不同的波特率。
4、硬件流控制:USART支持硬件流控制,通过特定的信号线(如RTS/CTS)实现数据的可靠传输。当接收端没有准备好接收数据时,可以通过RTS信号通知发送端暂停发送;当接收端准备好接收数据时,再通过CTS信号通知发送端恢复发送。【一般不用】
二、串口框图
STM32串口框图
如果感觉此图有些复杂,不访将其简化,下图为STM32串口简化图。
三、串口寄存器的介绍
结合上图,波特率到发送/接收之间由状态寄存器(USART_SR)控制。
状态寄存器(USART_SR)图
这里主要关注TXE、TC、RXNE、IDLE
数据寄存器:
数据寄存器图
主要配置数据的传送
波特比率寄存器:
波特比率寄存器图
控制寄存器1/2/3:
控制寄存器1
控制寄存器2
控制寄存器3:
四、串口相关函数的配置
以串口收发为例:
UART_HandleTypeDef uart1_handle = {0};
void uart1_init(uint32_t baudrate)
{uart1_handle.Instance = USART1; //串口选择uart1_handle.Init.BaudRate = baudrate; //波特率uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; //传输数据长度8位uart1_handle.Init.StopBits = UART_STOPBITS_1; //停止位uart1_handle.Init.Parity = UART_PARITY_NONE; //无校验位uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; //无硬件流控制uart1_handle.Init.Mode = UART_MODE_TX_RX; //RXTX双向通信HAL_UART_Init(&uart1_handle);
}void HAL_UART_MspInit(UART_HandleTypeDef *huart) //msp初始化GPIO、NVIC
{if(huart->Instance == USART1) //进一步判断是否串口一,防止出始化其他串口{__HAL_RCC_USART1_CLK_ENABLE(); //串口使能__HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef gpio_initstruct;//调用GPIO初始化函数gpio_initstruct.Pin = GPIO_PIN_9; // TX引脚gpio_initstruct.Mode = GPIO_MODE_AF_PP; // 复用推挽输出gpio_initstruct.Pull = GPIO_PULLUP; // 上拉gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速HAL_GPIO_Init(GPIOA, &gpio_initstruct);gpio_initstruct.Pin = GPIO_PIN_10; // RX引脚gpio_initstruct.Mode = GPIO_MODE_AF_INPUT; // 复用输入模式HAL_GPIO_Init(GPIOA, &gpio_initstruct);HAL_NVIC_EnableIRQ(USART1_IRQn);HAL_NVIC_SetPriority(USART1_IRQn, 2, 2);__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); //串口中断位,判断中断是否打开} //RXNE为数据是否接收位,为1则接收
}void USART1_IRQHandler(void) //中断服务函数
{uint8_t receive_data = 0;if(__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_RXNE) != RESET)//判断该位是否为一{HAL_UART_Receive(&uart1_handle, &receive_data, 1, 1000); //接收数据:串口、接收数据存储地、一位的移动、超时1000代表1sHAL_UART_Transmit(&uart1_handle, &receive_data, 1, 1000);}
}
关于接收、发送模式可参考附图
以上图均来自STM32中文参考手册