历史上的今天
返回首页

历史上的今天

今天是:2024年12月03日(星期二)

正在发生

2019年12月03日 | 关于STM32的USART_GetFlagStatus和USART_GetITStatus解析(异步通信)

2019-12-03 来源:eefocus

前言


STM32固件库中提供了串口收发的标志位函数,包括USART_GetFlagStatus(…,…);和USART_GetITStatus(…,…);,两者容易混淆,重点区别就在于:前者返回值是中断标志位状态(读SR寄存器),后者返回值是中断发生与否的判断(读CR寄存器),以下主要对这两个函数进行分析。


一、USART_GETFlagStatus(…,…)


/**

  * @brief  Checks whether the specified USART flag is set 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_FLAG: specifies the flag to check.

  *   This parameter can be one of the following values:

  *     @arg USART_FLAG_CTS:  CTS Change flag (not available for UART4 and UART5)

  *     @arg USART_FLAG_LBD:  LIN Break detection flag

  *     @arg USART_FLAG_TXE:  Transmit data register empty flag

  *     @arg USART_FLAG_TC:   Transmission Complete flag

  *     @arg USART_FLAG_RXNE: Receive data register not empty flag

  *     @arg USART_FLAG_IDLE: Idle Line detection flag

  *     @arg USART_FLAG_ORE:  OverRun Error flag

  *     @arg USART_FLAG_NE:   Noise Error flag

  *     @arg USART_FLAG_FE:   Framing Error flag

  *     @arg USART_FLAG_PE:   Parity Error flag

  * @retval The new state of USART_FLAG (SET or RESET).

  */

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)

{

  FlagStatus bitstatus = RESET;

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_FLAG(USART_FLAG));

  /* The CTS flag is not available for UART4 and UART5 */

  if (USART_FLAG == USART_FLAG_CTS)

  {

    assert_param(IS_USART_123_PERIPH(USARTx));

  }  


  if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)

  {

    bitstatus = SET;

  }

  else

  {

    bitstatus = RESET;

  }

  return bitstatus;

}


1.代码解析


该函数用于检测串口中断标志位的状态。 

其中,24、25、29三行用于检测所用参数是否符合该函数的范围。该函数的第一个形参只能是USART1,USART2,USART3,UART4,UART5,第二个形参只能是以下内容: 

 这里写图片描述 

从32行开始,检测SR寄存器的状态,在SET和RESET中进行比较。


2.函数使用


函数返回值为SET或RESET,即可直接用于判断。 

在没有使能相应的中断函数时,通常使用该函数来判断标志位是否置位。 

但串口触发中断后,需要清除标志位,由文章后部分描述。


二、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;  

}


1.代码解析


代码中分别读取串口控制寄存器CR1,CR2,CR3的状态,获取中断发生的动作,返回SET或RESET。 

这里写图片描述

2.函数使用


函数返回值为SET或RESET,即可直接用于判断。 

除了可以判断中断标志位外,还能判断是否发生了中断。 

但串口触发中断后,需要清除标志位,由文章后部分描述。


三、 USART_ClearFlag(…,…);


/**

  * @brief  Clears the USARTx's pending flags.

  * @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_FLAG: specifies the flag to clear.

  *   This parameter can be any combination of the following values:

  *     @arg USART_FLAG_CTS:  CTS Change flag (not available for UART4 and UART5).

  *     @arg USART_FLAG_LBD:  LIN Break detection flag.

  *     @arg USART_FLAG_TC:   Transmission Complete flag.

  *     @arg USART_FLAG_RXNE: Receive data register not empty flag.

  *   

  * @note

  *   - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun 

  *     error) and IDLE (Idle line detected) flags are cleared by software 

  *     sequence: a read operation to USART_SR register (USART_GetFlagStatus()) 

  *     followed by a read operation to USART_DR register (USART_ReceiveData()).

  *   - RXNE flag can be also cleared by a read to the USART_DR register 

  *     (USART_ReceiveData()).

  *   - TC flag can be also cleared by software sequence: a read operation to 

  *     USART_SR register (USART_GetFlagStatus()) followed by a write operation

  *     to USART_DR register (USART_SendData()).

  *   - TXE flag is cleared only by a write to the USART_DR register 

  *     (USART_SendData()).

  * @retval None

  */

void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)

{

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));

  /* The CTS flag is not available for UART4 and UART5 */

  if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS)

  {

    assert_param(IS_USART_123_PERIPH(USARTx));

  } 


  USARTx->SR = (uint16_t)~USART_FLAG;

}


1.代码解析


该函数用于软件清除标志位。 

例如,常用的参数为USART_FLAG_RXNE,库中定义的参数为0x0020,取反后为0xFFDF,恰好可以使SR寄存器的RXNE位置零(根据参考手册)。同时根据函数note,USART_FLAG_RXNE也可以通过读DR寄存器进行清位,即调用函数USART_ReceiveData();。


2.函数使用


可以用在中断处理函数中对标志位进行清除操作。


四、USART_ClearITPendingBit(…,…);


/**

  * @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

  */

void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)

{

  uint16_t bitpos = 0x00, itmask = 0x00;

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_CLEAR_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));

  }   


  bitpos = USART_IT >> 0x08;

  itmask = ((uint16_t)0x01 << (uint16_t)bitpos);

  USARTx->SR = (uint16_t)~itmask;

}


该函数与USART_ClearFlag(…,…);功能相同,都是对SR寄存器某位进行清除操作,只是概念不一样。 

例如,常用的参数为USART_IT_RXNE,库中定义的参数为0x0525,进入函数中itmask的值为0x20,取反为0xDF,恰好可以使SR寄存器的RXNE位置零(根据参考手册)。同时根据函数note,USART_FLAG_RXNE也可以通过读DR寄存器进行清位,即调用函数USART_ReceiveData();。

推荐阅读

史海拾趣

General Electric Company公司的发展小趣事
在电力电子变换器中,用于实现电压、电流的精确控制。
ERNI公司的发展小趣事

近年来,ERNI不断加大研发投入,致力于推出更多创新产品和技术。他们不仅继续深耕连接器领域,还拓展了背板、子系统及整套电机架系统等业务。同时,ERNI还积极为客户提供高性能、自行设计的工具制造、现代器件装配和测试设备等高附加值的服务。这些举措使ERNI在电子行业中的竞争力不断增强,也为公司的未来发展奠定了坚实基础。

以上是关于电子行业里ERNI公司发展起来的相关故事概述。通过这些故事,我们可以看到ERNI如何凭借持续的创新、精湛的技术和全球化的战略在电子行业中取得了辉煌成就。

Achronix Semiconductor Corporation公司的发展小趣事

近年来,ERNI不断加大研发投入,致力于推出更多创新产品和技术。他们不仅继续深耕连接器领域,还拓展了背板、子系统及整套电机架系统等业务。同时,ERNI还积极为客户提供高性能、自行设计的工具制造、现代器件装配和测试设备等高附加值的服务。这些举措使ERNI在电子行业中的竞争力不断增强,也为公司的未来发展奠定了坚实基础。

以上是关于电子行业里ERNI公司发展起来的相关故事概述。通过这些故事,我们可以看到ERNI如何凭借持续的创新、精湛的技术和全球化的战略在电子行业中取得了辉煌成就。

FOTEK公司的发展小趣事

福禄克并未止步于传统电子测试工具领域,而是积极探索新的增长点。2005年,公司推出了一系列室内空气质量(IAQ)测试工具,旨在为HVAC、建筑物维修和IAQ专业人员提供综合的精密仪器产品组合。这些产品凭借其精确性、可靠性和易用性,迅速获得了市场的认可。此后,福禄克进一步拓展至生物医学领域,推出了电气安全性测试仪、病患模拟器等先进设备,在生物医学测试和模拟产品领域取得了领先地位。

Changzhou Galaxy Century Microelectronics Co.,Ltd公司的发展小趣事

为了进一步加速企业的发展,银河微电决定走上上市之路。经过精心筹备和严格审核,公司终于在2021年成功在上交所上市。上市不仅为公司带来了大量的资金支持,还提高了公司的知名度和品牌影响力。借助上市融资的优势,银河微电加大了对研发、生产、销售等各个环节的投入,企业发展步入快车道。

ETEQ Microsystems Inc公司的发展小趣事

为了进一步扩大市场份额,ETEQ Microsystems Inc开始实施全球化战略。公司在亚洲、欧洲和北美等地设立了研发中心和销售办事处,并与多家国际知名企业建立了战略合作关系。这些举措不仅增强了公司的品牌影响力,还为公司带来了更多的商业机会。

问答坊 | AI 解惑

欧姆龙光电开关 EE-SX673 大量供应

本帖最后由 jameswangsynnex 于 2015-3-3 20:01 编辑 专业经营,大量现货,特价热卖,让你买的开心,用的放心 …

查看全部问答>

模拟电路设计有用资料

这些模拟电路设计资料,对于在设计电路时是很有用的!!…

查看全部问答>

新编电子电路大全·第4卷,测量与传感电路

新编电子电路大全·第4卷,测量与传感电路 [ 本帖最后由 lixiaohai8211 于 2010-2-14 16:27 编辑 ]…

查看全部问答>

串口信号的直流载波传输......新人求教~~~~~~~~~~~

小弟有个问题,要求通过串口控制单片机,控制信号的传输通过在电源线上加入载波实现 我感觉关键就是把信号调制到电源线上然后再解出来,剩下的就是单片机串口通信的工作了 现在就是想问一下怎么实现这个载波通讯,有没有简单一点的电路呢....... ...…

查看全部问答>

请问各位前辈一些问题

本人是电子信息工程专业的(大二,学校还未教授或介绍单片机和嵌入式),想问问搞单片机或嵌入式的需要考研或考研能提升自身水平吗?如果有,那个学校比较好?感激,但只能散一百分,我会认真给分的。不够的话,再开一个帖。继续散。…

查看全部问答>

QT视频教程

哪里有QT视频教程呀,这里的朋友能提供点信息吗?或者看什么样的书,学习QT,应该怎样学呢? 希望作界面图形开发的高手能给点意见.…

查看全部问答>

嵌入式开发群6462005

嵌入式开发群6462005…

查看全部问答>

如何设置在SRAM调试程序?

                                 请问:在SRAM中调试程序除了设置BOOT1和BOOT0以外,Keil中还需要做什么设置吗?我的板子只能在user flash中运 ...…

查看全部问答>