STM32F10X固件库函数——串口清状态位函数分析

最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解。下面是改函数的源码:

/*******************************************************************************

* Function Name  : USART_ClearFlag

* Description    : Clears the USARTx's pending flags.

* Input          : - USARTx: Select the USART or theUART peripheral.

*                    This parameter can be oneof the following values:

*                     - USART1, USART2, USART3,UART4 or UART5.

*                  - USART_FLAG: specifies theflag to clear.

*                    This parameter can be anycombination of the following values:

*                       - USART_FLAG_CTS:  CTS Change flag (not available for

*                                          UART4and UART5).

*                       - USART_FLAG_LBD:  LIN Break detection flag.

*                       - USART_FLAG_TC:   Transmission Complete flag.

*                       - USART_FLAG_RXNE:Receive data register not empty flag.

*                       - USART_FLAG_IDLE: IdleLine detection flag.

*                       - USART_FLAG_ORE:  OverRun Error flag.

*                       - USART_FLAG_NE:   Noise Error flag.

*                       - USART_FLAG_FE:   Framing Error flag.

*                       - USART_FLAG_PE:   Parity Error flag.

*

*                    Note: - For IDLE, ORE, NE, FE and PE flagsuser has to read

*                          the USART DR registerafter calling this function.

*                          - TXE flag can't becleared by this function, it's

*                          cleared only by a writeto the USART DR register.

* Output         : None

* Return         : None

*******************************************************************************/

void USART_ClearFlag(USART_TypeDef* USARTx,u16 USART_FLAG)

{

/*Check the parameters */

assert_param(IS_USART_ALL_PERIPH(USARTx));

assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));

assert_param(IS_USART_PERIPH_FLAG(USARTx, USART_FLAG)); /* The CTS flagis not available for UART4 and UART5 */

USARTx->SR =(u16)~USART_FLAG;

}

这些标志位的宏定义如下:

#define USART_FLAG_CTS                       ((u16)0x0200)

#define USART_FLAG_LBD                       ((u16)0x0100)

#define USART_FLAG_TXE                       ((u16)0x0080)

#define USART_FLAG_TC                        ((u16)0x0040)

#define USART_FLAG_RXNE                      ((u16)0x0020)

#define USART_FLAG_IDLE                      ((u16)0x0010)

#define USART_FLAG_ORE                       ((u16)0x0008)

#define USART_FLAG_NE                        ((u16)0x0004)

#define USART_FLAG_FE                        ((u16)0x0002)

#define USART_FLAG_PE                        ((u16)0x0001)

每一个宏定义对应着串口状态寄存器的一个状态位,我奇怪的是最后一句赋值操作:

USARTx->SR= (u16)~USART_FLAG;
 

执行完以后,不是将串口的其它状态位都赋为1了吗?为何不干脆写成下面的,
 USARTx->SR&= (u16)~USART_FLAG;

这样原来的状态位就可以保持不变了。

纠结了半天,觉得不可能是库函数有错误,翻看芯片手册,如下所示,10个状态位对应着不同的中断。关键的是这10个状态位都有这样一个说明,该位在某种条件下被硬件置高,由软件清0。

STM32F10X固件库函数——串口清状态位函数分析-LMLPHP

难道由硬件置高的状态位,软件对其写0,没有任何的影响,不会误操作引起中断?实际使用中,也确实没有发现带来什么坏处,软件写1以后,通过查看寄存器位发现没有改变。

04-26 10:09