STM32固件库中提供了串口收发的标志位函数,包括USART_GetFlagStatus(…,…);和USART_GetITStatus(…,…);两者容易混淆
区别就在于:前者返回值是中断标志位状态(读SR寄存器),后者返回值是中断发生与否的判断(读CR寄存器),以下主要对这两个函数进行分析。
一、USART_GETFlagStatus(…,…)
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 }
代码解析
该函数用于检测串口中断标志位的状态。
其中,24、25、29三行用于检测所用参数是否符合该函数的范围。该函数的第一个形参只能是USART1,USART2,USART3,UART4,UART5,第二个形参只能是以下内容:
从32行开始,检测SR寄存器的状态,在SET和RESET中进行比较。
2.函数使用
函数返回值为SET或RESET,即可直接用于判断
在没有使能相应的中断函数时,通常使用该函数来判断标志位是否置位。
但串口触发中断后,需要清除标志位,由文章后部分描述
二、USART_GetITStatus(…,…)
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(…,…)
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(…,…)
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(…,…);的函数说明里面都有各个参数的清位方式说明。