历史上的今天
返回首页

历史上的今天

今天是:2024年09月24日(星期二)

正在发生

2019年09月24日 | 关于STM32的USART_GetFlagStatus和USART_GetITStatus解析

2019-09-24 来源: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 */

推荐阅读

史海拾趣

EMCORE公司的发展小趣事

由于篇幅限制,我无法在此直接给出5个完整的500字以上的EMCORE公司发展故事。但我可以概述5个关于EMCORE公司在电子行业发展的关键点,每个点以简要的故事形式呈现,并尽量保持其客观性和事实性。

  1. 纳斯达克上市与早期发展

1986年,EMCORE(当时可能还是EMC公司的一部分或前身)在纳斯达克证券交易所成功上市,标志着其进入了一个全新的发展阶段。这一时期,公司可能通过融资和资本运作,为后续的技术研发和市场拓展奠定了坚实的基础。

  1. 技术创新与产品升级

在多年的发展历程中,EMCORE一直致力于技术创新和产品升级。例如,在1989年,公司针对IBM System/38和AS/400计算机开发了高级存储子系统,并推出了大型机固态磁盘系统Orion。这些创新不仅提升了公司的技术实力,也为其赢得了市场的认可。

  1. 与IBM等巨头的合作

EMCORE在发展过程中,与IBM等电子行业的巨头建立了紧密的合作关系。这种合作关系可能为公司带来了技术上的支持和市场上的机会,同时也提升了其在行业内的地位和影响力。

  1. 国际化布局

为了拓展国际市场,EMCORE在1988年在爱尔兰科克开设了欧洲制造工厂。这一举措不仅提升了公司的生产能力,也为其进入欧洲市场提供了便利。此后,公司可能还在其他国家和地区设立了分支机构或研发中心,以进一步推动其国际化进程。

  1. 与新奥集团的合作

近年来,EMCORE在新能源领域也取得了重要进展。例如,在2008年,公司与中国最大的能源公司之一新奥集团合作,在中国部署了第一个聚热光伏(CPV)系统。这一合作项目不仅展示了EMCORE在新能源技术方面的实力,也为其在中国的业务拓展提供了良好的契机。

请注意,以上故事是基于公开信息和行业知识进行的概括和推测,可能无法完全还原EMCORE公司发展的每一个细节。如需更详细的信息,建议查阅相关报道和资料。

BALLUFF公司的发展小趣事

随着中国经济的快速发展,BALLUFF公司也看到了中国市场的巨大潜力。为了更好地服务中国市场,BALLUFF在2007年坚定地走本土化路线,在成都建立了生产工厂。这一举措不仅缩短了亚洲地区的响应时间和供货周期,也极大地提升了客户满意度。随着工厂的正式运行,BALLUFF在中国市场的地位逐渐稳固,其传感器产品也广泛应用于汽车、冶金、机床和风电等行业。

Circuit Assembly公司的发展小趣事

随着自动化技术的不断进步,传感器技术的需求也日益增长。BALLUFF公司紧跟时代潮流,不断推出创新的传感器产品。从1968年开始生产感应式接近开关BES,到1978年光学开关BOS的面世,再到后来由微型处理器控制的转换机构与角度编码器的加入,BALLUFF在传感器领域的技术实力不断增强。此外,公司还陆续推出了旋转传感器BRG、识别系统BIS和超声波位移传感器BTL等产品,进一步丰富了其传感器产品线,满足了不同行业的需求。

BRIGHT公司的发展小趣事

随着BRIGHT公司在国际市场上的不断拓展,其品牌和产品也引起了一定的争议。在一些国家和地区,BRIGHT公司的某些行为或言论引发了公众的不满和批评。然而,这并没有阻挡BRIGHT公司前进的步伐。他们坚持自己的发展策略,通过不断创新和改进产品,积极应对各种挑战和机遇。在国际市场上,BRIGHT公司逐渐树立起了自己的品牌形象,并为电子行业的发展做出了重要的贡献。

这些故事展示了BRIGHT公司在电子行业中的不同领域所取得的成就和发展。无论是无线耳机领域的开创者、太阳能领域的突破者,还是健康技术领域的创新者、酒店业务的拓展者,以及在国际市场上的拓展与争议,都体现了BRIGHT公司不断创新、追求卓越的精神。这些故事不仅反映了BRIGHT公司的发展历程,也展示了电子行业的多样性和活力。

东软载波(EastSoft)公司的发展小趣事

东软载波公司成立于1993年,自成立之初就专注于电力载波通信技术的研发。公司在1996年开始了电力线载波通信技术的深入研究,经过数年的努力,终于在2000年推出了第一代电力线载波通信芯片。这一成果标志着东软载波在电力载波通信领域取得了重要突破,为其后续发展奠定了坚实的基础。

Harwin公司的发展小趣事

Harbour Industries成立于1965年,起初主要专注于电缆的生产与销售。在20世纪60年代末和70年代初期,随着全球航空航天市场的迅速增长,Harbour敏锐地捕捉到了这一机遇。为了服务这一市场,公司进行了大规模的工厂扩建,并引入了先进的生产设备和技术。这一举措不仅提升了公司的产能,还确保了产品质量能够满足航空领域的高标准。通过不懈努力,Harbour逐渐在航空电缆市场中占据了一席之地。

问答坊 | AI 解惑

DS18B20总是显示85℃。。。

我按照图1的电路接法,然后根据DS18B20的数据手册时序图编写代码,但总是85℃。。。请遇到过这种情况的电子爱好者指导一下: /***********ds18b20子程序*************************/ /******************************ds1820程序****************** ...…

查看全部问答>

为什么上电会有如此大的电流呢?

板子(数字)上电始会有一个大的过冲,大概有0.60A(12V上电,通过电源芯片转为3.3V输出供电),而且持续几秒,才会降到0.09A。 板上差不多只有一些SRAM,SDRAM,68013还是RS232电平转换芯片,电源块测过没问题,但是一旦连上后端电路,再上电就会 ...…

查看全部问答>

求职时被HR立即否决的9种人

一般来说,下面几类人,容易被HR快速拒绝。 开口言钱者不要 报酬不是不可以问,但得讲究时机和氛围。如果刚一交谈,就开门见山、直奔主题地问起薪酬待遇,会让企业感到很不舒服。 纠缠不休者不要。 招聘都遵循一定的流程,说几时给消息就几时给 ...…

查看全部问答>

win ce下键盘锁有什么实现思路?

请教各位高手,在下是win ce菜鸟,如果我想实现一个键盘锁,不考虑触摸屏,有啥实现思路没?…

查看全部问答>

wince下的汉子问题

请教大家一个问题: 我在wince下的edit控件中输入汉字、数字、字母,并保存在临时文件中。当我再次打开对话框,把临时文件中的东东全部放回edit控件时,数字和字母能正确显示,但是汉字只显示问号“?”!请问这是什么原因? 下面是代码 当edit ...…

查看全部问答>

3月31日ARM/Linux/WinCE讲座(上海)

时间:2007年03月31日下午1:00-5:00 地点:上海电力学院平凉路校区小礼堂(暂定) 路线:上海市杨浦区平凉路2103号 近隆昌路 专题1 基于ARM的嵌入式开发(13:30-14:30) 专题2 Windows CE揭秘(14:40-15:40) 专题3 嵌入式Linux系统平台构建 ...…

查看全部问答>

过年了,为庆祝在eeworld上的总技术分突破3000分,特散300分,先200分,往后加100分

过年了,为庆祝在eeworld上的总技术分突破3000分,特散300分,先200分,往后加100分…

查看全部问答>

最easy的一个问题,VxWorks下怎么控制评估板上的LED ?

VxWorks   +   ARM7   4510   的评估板, 在ADS下裸机编程调试通过了的一个LED闪灯程序。 把它加入到一个在VxWorks下已经可以运行的程序里面去后。(当然相应的头文件都加上了的) 编译下载,不能闪灯 ...…

查看全部问答>

路由设备NLME_GetCoordShortAddr() 获取的父地址与实际不一致

路由设备NLME_GetCoordShortAddr() 获取的父地址与实际不一致! 刚组网的时候NLME_GetCoordShortAddr() 获取的父地址与实际是一致的, 运行过程中,动态组网,父地址改变,NLME_GetCoordShortAddr() 获取的父地址就与实际不一致了。 有什么途 ...…

查看全部问答>

关于modelsim仿真问题!

本帖最后由 guaiguaidou 于 2015-7-27 10:48 编辑 最近学习特权同学的《深入浅出玩转FPGA》一书,想对里面的一个实验进行功能仿真(在书的p60) 但一直都得不到理想情况,请问这个是什么原因? 这是verilog代码: module handshack (   ...…

查看全部问答>