通用同步异步收发器(USART)既是串口,可以与电脑上的串口助手连接,是调试单片机的重要方式。双向通信至少需要2个引脚:接受数据输入(RX)和发送数据输出(TX)。
首先在STM32CubeMX中配置好使用串口的基本参数,开启串口中断,并将要是用的库设置为LL库:
自动生成好基础代码后,添加如下代码开启接收缓冲区Rx非空中断与空闲中断:
LL_USART_EnableIT_RXNE(USART2);
LL_USART_EnableIT_IDLE(USART2);
RXNE为接收缓冲器Rx非空标志,置1表明接收到了数据(1个字节),产生中断;IDLE为空闲标志,置1表明当前数据接收完毕(1帧数据),产生中断。接收不定长信息:
char data[20];
uint8_t Rflag = 0;
uint8_t Rnum = 0;
// 我们将接收到的数据存入字符串数组data[]中,Rnum表明数据长度,Rflag表示接收状态,=1即接收完毕
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
// 空闲中断,表明接收到了1帧所有的数据
if(LL_USART_IsActiveFlag_IDLE(USART2)){
// 清楚中断标志位
LL_USART_ClearFlag_IDLE(USART2);
data[Rnum] = '\0';
Rflag = 1;
Rnum = 0;
}
// Rx非空中断,表明接收到了一个字节
// 读取Rx可自动清除中断标志位
if(LL_USART_IsActiveFlag_RXNE(USART2)){
// 如果数组长度大于设置的data最大长度,直接停止接收
if(Rnum > 18){
data[19] = '\0';
Rflag = 1; // stop receive
Rnum = 0; // wait for the next data
}
if(Rflag == 0){
data[Rnum] = LL_USART_ReceiveData8(USART2);
Rnum ++;
}
}
WRITE_REG(USART2->RQR, USART_RQR_RXFRQ);
/* USER CODE END USART2_IRQn 0 */
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
相关LL库函数定义如下:
/* Legacy define */
#define LL_USART_EnableIT_RXNE LL_USART_EnableIT_RXNE_RXFNE
/**
* @brief Enable RX Not Empty and RX FIFO Not Empty Interrupt
* @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not
* FIFO mode feature is supported by the USARTx instance.
* @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_EnableIT_RXNE_RXFNE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_RXNE_RXFNE(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE);
}
/**
* @brief Enable IDLE Interrupt
* @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR1, USART_CR1_IDLEIE);
}
/**
* @brief Read Receiver Data register (Receive Data value, 8 bits)
* @rmtoll RDR RDR LL_USART_ReceiveData8
* @param USARTx USART Instance
* @retval Value between Min_Data=0x00 and Max_Data=0xFF
*/
__STATIC_INLINE uint8_t LL_USART_ReceiveData8(USART_TypeDef *USARTx)
{
return (uint8_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR) & 0xFFU);
}