/**
* @brief Checks whether the specified USART interrupt has occurred or not.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param USART_IT: specifies the USART interrupt source to check.
* This parameter can be one of the following values:
* @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
* @arg USART_IT_LBD: LIN Break detection interrupt
* @arg USART_IT_TXE: Tansmit Data Register empty interrupt
* @arg USART_IT_TC: Transmission complete interrupt
* @arg USART_IT_RXNE: Receive Data register not empty interrupt
* @arg USART_IT_IDLE: Idle line detection interrupt
* @arg USART_IT_ORE: OverRun Error interrupt
* @arg USART_IT_NE: Noise Error interrupt
* @arg USART_IT_FE: Framing Error interrupt
* @arg USART_IT_PE: Parity Error interrupt
* @retval The new state of USART_IT (SET or RESET).
*/
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
{
uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
ITStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_GET_IT(USART_IT));
/* The CTS interrupt is not available for UART4 and UART5 */
if (USART_IT == USART_IT_CTS)
{
assert_param(IS_USART_123_PERIPH(USARTx));
}
/* Get the USART register index */
usartreg = (((uint8_t)USART_IT) >> 0x05);
/* Get the interrupt position */
itmask = USART_IT & IT_Mask;
itmask = (uint32_t)0x01 << itmask;
if (usartreg == 0x01) /* The IT is in CR1 register */
{
itmask &= USARTx->CR1;
}
else if (usartreg == 0x02) /* The IT is in CR2 register */
{
itmask &= USARTx->CR2;
}
else /* The IT is in CR3 register */
{
itmask &= USARTx->CR3;
}
bitpos = USART_IT >> 0x08;
bitpos = (uint32_t)0x01 << bitpos;
bitpos &= USARTx->SR;
if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/**
* @brief Clears the USARTx's interrupt pending bits.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param USART_IT: specifies the interrupt pending bit to clear.
* This parameter can be one of the following values:
* @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
* @arg USART_IT_LBD: LIN Break detection interrupt
* @arg USART_IT_TC: Transmission complete interrupt.
* @arg USART_IT_RXNE: Receive Data register not empty interrupt.
*
* @note
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
* error) and IDLE (Idle line detected) pending bits are cleared by
* software sequence: a read operation to USART_SR register
* (USART_GetITStatus()) followed by a read operation to USART_DR register
* (USART_ReceiveData()).
* - RXNE pending bit can be also cleared by a read to the USART_DR register
* (USART_ReceiveData()).
* - TC pending bit can be also cleared by software sequence: a read
* operation to USART_SR register (USART_GetITStatus()) followed by a write
* operation to USART_DR register (USART_SendData()).
* - TXE pending bit is cleared only by a write to the USART_DR register
* (USART_SendData()).
* @retval None
*/
首先我们要知道的是
在stm32f10x_usart.h中有以下宏定义:
#define IT_Mask ((uint16_t)0x001F) /*!< USART Interrupt Mask */
#define USART_IT_PE ((uint16_t)0x0028)
#define USART_IT_TXE ((uint16_t)0x0727)
#define USART_IT_TC ((uint16_t)0x0626)评论和@
#define USART_IT_RXNE ((uint16_t)0x0525)
#define USART_IT_IDLE ((uint16_t)0x0424)
#define USART_IT_LBD ((uint16_t)0x0846)
#define USART_IT_CTS ((uint16_t)0x096A)
#define USART_IT_ERR ((uint16_t)0x0060)
#define USART_IT_ORE ((uint16_t)0x0360)
#define USART_IT_NE ((uint16_t)0x0260)
#define USART_IT_FE ((uint16_t)0x0160)
需要重点注意的是以上标志都为16位,在此函数中可能被强制转换为8位后进行移位(与原不进行转换的结果明显不同)!!
Tips:
USART_GetFlagStatus(…,…);和USART_GetITStatus(…,…);两者容易混淆
区别就在于:前者返回值是中断标志位状态(读SR寄存器),后者返回值是中断发生与否的判断(读CR寄存器)。
以上宏定义的标志位的含义如下(Dx---表示二进制中的第x位):
D0~D4:代表中断标志位对应的中断使能位在CRx寄存器的哪一位
D5~D7:代表中断标志位对应的中断使能位在 CR1、CR2还是CR3寄存器中
D8~D15:代表中断标志位在SR寄存器中的哪一位
此函数的返回值bitstatus是由
if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
判断为SET or RESET
itmask部分:
usartreg = (((uint8_t)USART_IT) >> 0x05); //D5~D7:代表中断标志位对应的中断使能位在 CR1、CR2还是CR3寄存器中
不管是几进制都是先转换为二进制后移位
0x0727 = 027(八进制标志是首位为0) >> 0x05 = 010 111 >> 5 = 000 001 = 1
后会进行判断:
if (usartreg == 0x01)
{
itmask &= USARTx->CR1;
}
else if (usartreg == 0x02)
{
itmask &= USARTx->CR2;
}
else
{
itmask &= USARTx->CR3;
}
而
itmask = USART_IT & IT_Mask;
itmask = (uint32_t)0x01 << itmask; //D0~D4:代表中断标志位对应的中断使能位在CRx寄存器的哪一位(各种标志位均占据着寄存器的各个位,为1代表检测到了标志位)
bitpos 部分:
-
bitpos = USART_IT >> 0x08; //D8~D15:代表中断标志位在SR寄存器中的哪一位
-
bitpos = (uint32_t)0x01 << bitpos;
-
bitpos &= USARTx->SR;