STM32串口通信HAL库配置中 UART_IT_xx与UART_FLAG_xx 的区别:
(最后有个疑问希望路过的大佬帮忙解答一下。)
UART_IT_xx
刚开始疑惑的时候,发现网上都没有解释UART_IT_TC、UART_IT_RXNE这些标志的,(所以其实查HAL库才是不二法门)于是看了下HAL库。
从UART_IT_RXNE入手,搜了一通,发现
代码如下
/** @brief Enable the specified UART interrupt.
* @param __HANDLE__: specifies the UART Handle.
* This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or
* UART peripheral.
* @param __INTERRUPT__: specifies the UART interrupt source to enable.
* This parameter can be one of the following values:
* @arg UART_IT_CTS: CTS change interrupt
* @arg UART_IT_LBD: LIN Break detection interrupt
* @arg UART_IT_TXE: Transmit Data Register empty interrupt
* @arg UART_IT_TC: Transmission complete interrupt
* @arg UART_IT_RXNE: Receive Data register not empty interrupt
* @arg UART_IT_IDLE: Idle line detection interrupt
* @arg UART_IT_PE: Parity Error interrupt
* @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
* @retval None
*/
#define UART_IT_MASK ((uint32_t)0x0000FFFF)
#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
(((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
UART_IT_RXNE其实是__HAL_UART_ENABLE_IT(HANDLE, INTERRUPT) 的第二个参数,猜想到这个参数可能只是配置中断的,于是去查看了UART_Receive_IT函数,发现内部确实调用了__HAL_UART_ENABLE_IT
所以,其实可以看到UART_IT_xxxx这类的,就是用来配置中断的,他们都在HAL库内部被封装好了,不需要我们来调用了。
UART_FLAG_xx
其实我们一般会去调用的是UART_FLAG_TC、UART_FLAG_RXNE这类标志。它是指串口数据发送或接收完成的标志。
从UART_FLAG_TC入手来看:
从F4官方手册中查找到TC的解释如下图
HAL库中定义的标志位解释:UART_FLAG_TC: Transmission Complete flag.
简言之:当发送数据寄存器中的数据已经取完了,该标志位就会被硬件置1,从而引发该事件的中断。
对应的函数:
- __HAL_UART_GET_FLAG :
获取 SR 寄存器标志位状态 - __HAL_UART_CLEAR_FLAG
清除 SR 寄存器标志位状态,不同于读改写的清零方式,这是直接清零。
(SR是硬件自动置1,一般都是软件清零,读取USART_SR 寄存器,然后写入 USART_DR 寄存器,通过读改写方式清零会导致中断请求丢失,推荐软件直接写0清除标志)
/** @brief Checks whether the specified UART flag is set or not.
* @param __HANDLE__: specifies the UART Handle.
* This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or
* UART peripheral.
* @param __FLAG__: specifies the flag to check.
* This parameter can be one of the following values:
* @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
* @arg UART_FLAG_LBD: LIN Break detection flag
* @arg UART_FLAG_TXE: Transmit data register empty flag
* @arg UART_FLAG_TC: Transmission Complete flag
* @arg UART_FLAG_RXNE: Receive data register not empty flag
* @arg UART_FLAG_IDLE: Idle Line detection flag
* @arg UART_FLAG_ORE: Overrun Error flag
* @arg UART_FLAG_NE: Noise Error flag
* @arg UART_FLAG_FE: Framing Error flag
* @arg UART_FLAG_PE: Parity Error flag
* @retval The new state of __FLAG__ (TRUE or FALSE).
*/
#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
使用示例:
while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC) != SET);
疑问:
这里有个地方感觉理解比较模糊:
我们判断串口发送数据是否完成有两种方法:
1.中断
2.查询。
那么while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC) != SET);这种就是手动查询吗??如果是,那这个手动查询有没有自动清空标志位呢???
希望路过的大佬帮忙解答一下。