HAL_UART_Receive_IT和HAL_UART_IRQHandler

https://blog.youkuaiyun.com/qq_45413245/article/details/104585026

HAL_UART_Receive_IT和HAL_UART_IRQHandler相互配合;HAL_UART_Receive_IT用于打开串口数据接收中断(RxNEIE),并将用于保存接收数据的变量地址传递给指针pRxBuffPtr。串口在接收到1Byte数据后会产生中断,在中断处理函数中调用HAL_UART_IRQHandler,HAL_UART_IRQHandler再调用UART_Receive_IT将DR寄存器上的值赋值给pRxBuffPtr所指向的变量,同时将RxXferCount递减,待RxXferCount减至0(即数据读取完毕),然后关闭接收中断,调用回调函数HAL_UART_RxCpltCallback,这就完成了一个数据接收的完整流程。

1.(HAL_UART_Receive_IT打开接收中断,保存接收数据地址)-->2.(串口接收到数据产生中断调用USART1_IRQHandler) -->3.(HAL_UART_IRQHandler)--> 4.(UART_Receive_IT读取DR保存到pRxBuffPtr指向的变量,RxXferCount !=0重复流程2-4) --> 5.(关接收中断,调用回调函数HAL_UART_RxCpltCallback)

既然用到指针pRxBuffPtr就涉及一个问题:如果使用局部变量来保存接收数据就要注意,在产生中断读取到数据前变量不能被回收,否则会导致pRxBuffPtr成为一个野指针。

如果不使用HAL_UART_Receive_IT,就要手动使能接收中断__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE)。手动使能接收中断后,因为pRxBuffPtr为NULL,需要在中断函数USART1_IRQHandler中直接读取DR寄存器的值。读取DR值后SR的RXNE位会被清零,在这之后再调用HAL_UART_IRQHandler的话,由于RXNE被清零条件判断不会操作pRxBuffPtr读取DR寄存器,中断不会被关闭,回调函数HAL_UART_RxCpltCallback也不会被执行。

/* 使能UART接收中断 */
void Enable_Rx_ISR(void)
{
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
}

void USART1_IRQHandler(void)
{
    unsigned char c = 0;
    if((USART1->SR &(1<<5)) != 0)  // 判断USART1的状态寄存器的第五位即RXNE位是否被置位
    {
        c = USART1->DR;            // 读取DR,SR寄存器RXNE位会被清零
        ring_buffer_write(c, &test_buffer); // 将数据保存到环形缓冲区中
    }

    /* HAL库中的UART统一中断服务函数,通过形参判断是要处理谁的中断 */
    HAL_UART_IRQHandler(&huart1);    // 对于接收中断,这个函数没有任何作用
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值