串口空闲中断(UART_IT_IDLE):串口接收数据,超过一个字节的时间内没有再接收到数据的时候发生的
好处:与传统的判断'\r','\n'为结束位相比,空闲中断判断串口数据接收完毕准确且迅速
缺点:串口持续不断的发送数据时,无法进入空闲中断。因此需要间隔一个字节以上的时间,间歇式的发送数据。这个缺点在正常使用中,根本不是问题
下面进入主题
打开STM32CubeMX,配置如下:
程序中配置:
在usart.c文件中创建接收数组和处理函数:
#define USART1_RX_MAX 2148
uint8_t Rxbuf[USART1_RX_MAX];
uint16_t Rxlen=0;
void Usart_Receive_Data(UART_HandleTypeDef *huart)
{
if(RESET != __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) //判断是否是空闲中断
{
//清除空闲中断标志(否则会一直不断进入中断)
__HAL_UART_CLEAR_IDLEFLAG(huart);
//计算接收到的数据量
Rxlen = (USART1_RX_MAX) - (__HAL_DMA_GET_COUNTER(&hdma_usart1_rx));
//停止接收
HAL_UART_DMAStop(huart);
}
}
这里需要注意添加: HAL_UART_DMAStop(huart);//停止接收
不添加的话,DMA接收不会停止,重新开启DMA接收,RX缓存将不会从0开始接收数据
在stm32f1xx_it.c文件中调用Usart_Receive_Data():
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
Usart_Receive_Data(&huart1);//调用函数
/* USER CODE END USART1_IRQn 1 */
}
在main.c文件中的main()函数中开启空闲中断并启动DMA:
在main()函数中,判断Rxlen大于0,则开始处理串口数据:
int main(void)
{
//初始化
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//开启空闲中断
HAL_UART_Receive_DMA(&huart1,Rxbuf,USART1_RX_MAX); //启动DMA接收
while(1)
{
if(Rxlen>0){
//处理串口数据
//清空串口缓存并Rxlen=0
memset(Rxbuf,0,USART1_RX_MAX);
Rxlen=0;
//重新开启DMA接收
HAL_UART_Receive_DMA(&huart1,Rxbuf,USART1_RX_MAX); //启动DMA接收
}
}
}