关于STM32的USART_GetFlagStatus和USART_GetITStatus解析(异步通信)

2019-12-03来源: eefocus关键字:STM32  USART_GetFlagStatus  USART_GetITStatus  异步通信

前言


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

[1] [2]
关键字:STM32  USART_GetFlagStatus  USART_GetITStatus  异步通信 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic481834.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm8s iar printf打印信息
下一篇:STM32 死在 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8S存储器的读写操作
/************************************************************************************************************************************ Name    : STM8S存储器的读写操作* Author  : MingMing* Release : 2014/1/2* Update  : 2014/1/2* E-mail  : clint.wang@foxmail.com
发表于 2019-12-05
stm8l051 halt之后外部中断唤醒问题
最近用到stm8l051 halt,在halt之后开启了外部中断,有时灵,有时不灵,设置下降沿触发,但是按键(低有效)放开了才会从HALT退出,最后发现在进去外部中断的时候一直在外部中断里面不退出。在外部中断程序里面把端口的外部中断和端口使能的外部中断功能关闭,问题解决,可以在下降沿从halt退出。1、开启halt,其他代码省略,只贴halt部分:    /* 禁止TIM3 */    TIM3->SR1 = (uint8_t)(~(uint8_t)TIM3_IT_Update);    CLK_PeripheralClockConfig
发表于 2019-12-05
STM8L052低功耗模式
Stm8L系列单片机的低功耗有五种模式:§ wait模式§ Lowpower run模式§ Lowpower wait模式§ Active-haltwith full RTC模式§ Halt模式最低功耗的就是就是halt模式。这里也主要总结一下如何进入halt模式,进入以后可以通过什么方式唤醒,以及有很多客户会关心的如何自动唤醒。Halt模式进入很简单,执行一条halt指令,调用库函数也就是halt()就行了。但是进入前要注意把所有的中断挂起标志给清除掉。要是不清零又恰巧有中断标志的时候进入该模式也会被立马唤醒。进入这种模式,所有的外设全都关闭了,所有时钟关闭。这时候它自己是醒不过来的,只能靠掐人中(给个外部中断)或者重新复活
发表于 2019-12-05
解决STM8类型单片机空间太小,使用不了printf串口打印问题
概述:在使用STM8L101F3这款单片机时,由于它只有8K的flash,空间非常小,只要调用C库函数printf编译后整个文件很大,直接程序溢出。这也就意味着我们实现printf串口打印调试就没办法进行。既然使用不了库函数,那么我们就可以自己动手封装类似printf的函数,这样我们就可以实现数据串口打印啦。这里就直接放上我的STM8L101F3的部分源码了,希望可以给你一些参考。源码:#include "stdarg.h"#include "stm8l10x.h" void USART_Config(void){    /*Set the USART RX
发表于 2019-12-04
解决STM8类型单片机空间太小,使用不了printf串口打印问题
基于STM8的IIC协议--协议篇
4.3.8代码示例。3.6 数据有效性  I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。3.7 I2C通信总过程 4. 例程4.1 编译环境:  我的编译环境是IAR,这款软件是现在STM8的主流平台,比较推荐。不过我打算等到STCubeMX更新出比较方便的版本后再去使用Keil5,因为我在用STM32的时候就是利用Keil5,的确很方便,你们也可以学着用一下。4.2 主芯片:  我的主芯片是STM8S系列中的103,其中STM8S的003、005、和103、105,配置一样(外设和CPU频率,FLASH),在代码相同的
发表于 2019-12-04
基于STM8的IIC协议--协议篇
基于STM8的ADC读取---STM8-第四章
和连续转换的扫描模式具有上限和下限门槛的模拟看门狗模拟看门狗时间发生可产生中断----------------------------------------------------------------------------------------------------------------------------------3. 例程3.1 编译环境  我的编译环境是IAR,这款软件是现在STM8的主流平台,比较推荐。不过我打算等到STCubeMX更新出比较方便的版本后再去使用Keil5,因为我在用STM32的时候就是利用Keil5,的确很方便,你们也可以学着用一下。3.2 主芯片  我的主芯片是STM8S系列中的103
发表于 2019-12-04
基于STM8的ADC读取---STM8-第四章
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved