关于USART_GetITStatus函数的分析


/**
  * @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 部分:

  1. bitpos = USART_IT >> 0x08; //D8~D15:代表中断标志位在SR寄存器中的哪一位

  2. bitpos = (uint32_t)0x01 << bitpos;

  3. bitpos &= USARTx->SR;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值