前言
STM32固件库中提供了串口收发的标志位函数,包括USART_GetFlagStatus(…,…);和USART_GetITStatus(…,…);,两者容易混淆,重点区别就在于:前者返回值是中断标志位状态(读SR寄存器),后者返回值是中断发生与否的判断(读CR寄存器),以下主要对这两个函数进行分析。
一、USART_GETFlagStatus(…,…)
1 /** 2 * @brief Checks whether the specified USART flag is set or not. 3 * @param USARTx: Select the USART or the UART peripheral. 4 * This parameter can be one of the following values: 5 * USART1, USART2, USART3, UART4 or UART5. 6 * @param USART_FLAG: specifies the flag to check. 7 * This parameter can be one of the following values: 8 * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) 9 * @arg USART_FLAG_LBD: LIN Break detection flag 10 * @arg USART_FLAG_TXE: Transmit data register empty flag 11 * @arg USART_FLAG_TC: Transmission Complete flag 12 * @arg USART_FLAG_RXNE: Receive data register not empty flag 13 * @arg USART_FLAG_IDLE: Idle Line detection flag 14 * @arg USART_FLAG_ORE: OverRun Error flag 15 * @arg USART_FLAG_NE: Noise Error flag 16 * @arg USART_FLAG_FE: Framing Error flag 17 * @arg USART_FLAG_PE: Parity Error flag 18 * @retval The new state of USART_FLAG (SET or RESET). 19 */ 20 FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) 21 { 22 FlagStatus bitstatus = RESET; 23 /* Check the parameters */ 24 assert_param(IS_USART_ALL_PERIPH(USARTx)); 25 assert_param(IS_USART_FLAG(USART_FLAG)); 26 /* The CTS flag is not available for UART4 and UART5 */ 27 if (USART_FLAG == USART_FLAG_CTS) 28 { 29 assert_param(IS_USART_123_PERIPH(USARTx)); 30 } 31 32 if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) 33 { 34 bitstatus = SET; 35 } 36 else 37 { 38 bitstatus = RESET; 39 } 40 return bitstatus; 41 }
1.代码解析
该函数用于检测串口中断标志位的状态。
其中,24、25、29三行用于检测所用参数是否符合该函数的范围。该函数的第一个形参只能是USART1,USART2,USART3,UART4,UART5,第二个形参只能是以下内容:
从32行开始,检测SR寄存器的状态,在SET和RESET中进行比较。
2.函数使用
函数返回值为SET或RESET,即可直接用于判断
在没有使能相应的中断函数时,通常使用该函数来判断标志位是否置位。
但串口触发中断后,需要清除标志位,由文章后部分描述
二、USART_GetITStatus(…,…)
1 /** 2 * @brief Checks whether the specified USART interrupt has occurred or not. 3 * @param USARTx: Select the USART or the UART peripheral. 4 * This parameter can be one of the following values: 5 * USART1, USART2, USART3, UART4 or UART5. 6 * @param USART_IT: specifies the USART interrupt source to check. 7 * This parameter can be one of the following values: 8 * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) 9 * @arg USART_IT_LBD: LIN Break detection interrupt 10 * @arg USART_IT_TXE: Tansmit Data Register empty interrupt 11 * @arg USART_IT_TC: Transmission complete interrupt 12 * @arg USART_IT_RXNE: Receive Data register not empty interrupt 13 * @arg USART_IT_IDLE: Idle line detection interrupt 14 * @arg USART_IT_ORE: OverRun Error interrupt 15 * @arg USART_IT_NE: Noise Error interrupt 16 * @arg USART_IT_FE: Framing Error interrupt 17 * @arg USART_IT_PE: Parity Error interrupt 18 * @retval The new state of USART_IT (SET or RESET). 19 */ 20 ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) 21 { 22 uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; 23 ITStatus bitstatus = RESET; 24 /* Check the parameters */ 25 assert_param(IS_USART_ALL_PERIPH(USARTx)); 26 assert_param(IS_USART_GET_IT(USART_IT)); 27 /* The CTS interrupt is not available for UART4 and UART5 */ 28 if (USART_IT == USART_IT_CTS) 29 { 30 assert_param(IS_USART_123_PERIPH(USARTx)); 31 } 32 33 /* Get the USART register index */ 34 usartreg = (((uint8_t)USART_IT) >> 0x05); 35 /* Get the interrupt position */ 36 itmask = USART_IT & IT_Mask; 37 itmask = (uint32_t)0x01 << itmask; 38 39 if (usartreg == 0x01) /* The IT is in CR1 register */ 40 { 41 itmask &= USARTx->CR1; 42 } 43 else if (usartreg == 0x02) /* The IT is in CR2 register */ 44 { 45 itmask &= USARTx->CR2; 46 } 47 else /* The IT is in CR3 register */ 48 { 49 itmask &= USARTx->CR3; 50 } 51 52 bitpos = USART_IT >> 0x08; 53 bitpos = (uint32_t)0x01 << bitpos; 54 bitpos &= USARTx->SR; 55 if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) 56 { 57 bitstatus = SET; 58 } 59 else 60 { 61 bitstatus = RESET; 62 } 63 64 return bitstatus; 65 }
1.代码解析
代码中分别读取串口控制寄存器CR1,CR2,CR3的状态,获取中断发生的动作,返回SET或RESET。
2.函数使用
函数返回值为SET或RESET,即可直接用于判断。
除了可以判断中断标志位外,还能判断是否发生了中断。
但串口触发中断后,需要清除标志位,由文章后部分描述
三、 USART_ClearFlag(…,…)
1 /** 2 * @brief Clears the USARTx's pending flags. 3 * @param USARTx: Select the USART or the UART peripheral. 4 * This parameter can be one of the following values: 5 * USART1, USART2, USART3, UART4 or UART5. 6 * @param USART_FLAG: specifies the flag to clear. 7 * This parameter can be any combination of the following values: 8 * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). 9 * @arg USART_FLAG_LBD: LIN Break detection flag. 10 * @arg USART_FLAG_TC: Transmission Complete flag. 11 * @arg USART_FLAG_RXNE: Receive data register not empty flag. 12 * 13 * @note 14 * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun 15 * error) and IDLE (Idle line detected) flags are cleared by software 16 * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) 17 * followed by a read operation to USART_DR register (USART_ReceiveData()). 18 * - RXNE flag can be also cleared by a read to the USART_DR register 19 * (USART_ReceiveData()). 20 * - TC flag can be also cleared by software sequence: a read operation to 21 * USART_SR register (USART_GetFlagStatus()) followed by a write operation 22 * to USART_DR register (USART_SendData()). 23 * - TXE flag is cleared only by a write to the USART_DR register 24 * (USART_SendData()). 25 * @retval None 26 */ 27 void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) 28 { 29 /* Check the parameters */ 30 assert_param(IS_USART_ALL_PERIPH(USARTx)); 31 assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); 32 /* The CTS flag is not available for UART4 and UART5 */ 33 if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS) 34 { 35 assert_param(IS_USART_123_PERIPH(USARTx)); 36 } 37 38 USARTx->SR = (uint16_t)~USART_FLAG; 39 }
1.代码解析
该函数用于软件清除标志位。
例如,常用的参数为USART_FLAG_RXNE,库中定义的参数为0x0020,取反后为0xFFDF,恰好可以使SR寄存器的RXNE位置零(根据参考手册)。同时根据函数note,USART_FLAG_RXNE也可以通过读DR寄存器进行清位,即调用函数USART_ReceiveData();。
2.函数使用
可以用在中断处理函数中对标志位进行清除操作。
四、USART_ClearITPendingBit(…,…)
1 /** 2 * @brief Clears the USARTx's interrupt pending bits. 3 * @param USARTx: Select the USART or the UART peripheral. 4 * This parameter can be one of the following values: 5 * USART1, USART2, USART3, UART4 or UART5. 6 * @param USART_IT: specifies the interrupt pending bit to clear. 7 * This parameter can be one of the following values: 8 * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) 9 * @arg USART_IT_LBD: LIN Break detection interrupt 10 * @arg USART_IT_TC: Transmission complete interrupt. 11 * @arg USART_IT_RXNE: Receive Data register not empty interrupt. 12 * 13 * @note 14 * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun 15 * error) and IDLE (Idle line detected) pending bits are cleared by 16 * software sequence: a read operation to USART_SR register 17 * (USART_GetITStatus()) followed by a read operation to USART_DR register 18 * (USART_ReceiveData()). 19 * - RXNE pending bit can be also cleared by a read to the USART_DR register 20 * (USART_ReceiveData()). 21 * - TC pending bit can be also cleared by software sequence: a read 22 * operation to USART_SR register (USART_GetITStatus()) followed by a write 23 * operation to USART_DR register (USART_SendData()). 24 * - TXE pending bit is cleared only by a write to the USART_DR register 25 * (USART_SendData()). 26 * @retval None 27 */ 28 void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) 29 { 30 uint16_t bitpos = 0x00, itmask = 0x00; 31 /* Check the parameters */ 32 assert_param(IS_USART_ALL_PERIPH(USARTx)); 33 assert_param(IS_USART_CLEAR_IT(USART_IT)); 34 /* The CTS interrupt is not available for UART4 and UART5 */ 35 if (USART_IT == USART_IT_CTS) 36 { 37 assert_param(IS_USART_123_PERIPH(USARTx)); 38 } 39 40 bitpos = USART_IT >> 0x08; 41 itmask = ((uint16_t)0x01 << (uint16_t)bitpos); 42 USARTx->SR = (uint16_t)~itmask; 43 }
该函数与USART_ClearFlag(…,…);功能相同,都是对SR寄存器某位进行清除操作,只是概念不一样。
例如,常用的参数为USART_IT_RXNE,库中定义的参数为0x0525,进入函数中itmask的值为0x20,取反为0xDF,恰好可以使SR寄存器的RXNE位置零(根据参考手册)。同时根据函数note,USART_FLAG_RXNE也可以通过读DR寄存器进行清位,即调用函数USART_ReceiveData();。
备注:
USART_ClearFlag(…,…);和USART_ClearITPendingBit(…,…);的函数说明里面都有各个参数的清位方式说明。
来源:https://www.cnblogs.com/renhao1024/p/12010809.html