USART_ClearITPendingBith和 USART_ClearFlag的区别

发布者:开元轩最新更新时间:2019-09-24 来源: eefocus关键字:USART_ClearITPendingBith  USART_ClearFlag  区别 手机看文章 扫描二维码
随时随地手机看文章

起初

stm32 v3.5 库函数里面,对于串口USART有这样两个函数:

                USART_ClearFlag()和USART_ClearITPendingBit()



查库函数定义,说一个是清除标志,一个是清除中断预处理位。然后我看了stm32f10x_usart.c文件,发现两个函数都操作的是USART->SR寄存器,但是这个寄存器只有一组标志位,没有什么中断预处理位。。


实际上两个函数实现的功能是一样的,都是清除相对应的标志位,只是标志位和中断位含义不一样,是标志位但

是不一定会产生中断。例如:

#define USART_IT_TXE                         ((uint16_t)0x0727)

#define USART_IT_TC                          ((uint16_t)0x0626)

#define USART_IT_RXNE                        ((uint16_t)0x0525)

这是中断位,可以产生中断

 

#define USART_FLAG_TXE                       ((uint16_t)0x0080)

#define USART_FLAG_TC                        ((uint16_t)0x0040)

#define USART_FLAG_RXNE                      ((uint16_t)0x0020)

这是标志位,有的标志位不能产生中断

 

标志位在程序中可以作为判定条件,支持程序的运行,中断则是跳转到中断函数执行。两个函数实现的功能是一

样的,在中断程序中可以用两个中的任一个。我想区分两个函数是为了更清晰吧。

还有

#define USART_IT_TC                          ((uint16_t)0x0626)

#define USART_FLAG_TC                        ((uint16_t)0x0040)

 

这两个数值不同是因为标志位只是为了清除标志位而设的,而中断位设置成这个值是因为在其他函数中这一位还

有其他用途。而且还要注意:

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));

  assert_param(IS_USART_PERIPH_FLAG(USARTx, USART_FLAG)); /* The CTS flag is not available for UART4 and UART5 */   

   

  USARTx->SR = (uint16_t)~USART_FLAG;

}

 

 这一步 USARTx->SR = (uint16_t)~USART_FLAG; 似乎应该是  USARTx->SR &= (uint16_t)~USART_FLAG;

其实状态位只能有硬件置位,软件只能读和清零,所以这样写也是正确的。

没有很明白,所以转在这里,等我哪天灵光乍现了,再来加上我的理解

上面的内容是别人的,我略作修改,下面的内容是我原创。不知道本文到底是属于原创还是转载,但是......我的更简洁、精辟


 -----------------------------------------------------------------------------------------------------------------------


灵光乍现了

我是在使用TC的时候遇见这个问题的,所以这里就只分析TC这个位


先研究简单点的USART_ClearFlag函数


//调用形式

USART_ClearFlag(USART3,USART_FLAG_TC);

 

//USART_FLAG_TC的定义

#define USART_FLAG_TC               ((uint16_t)0x0040)

 

//USART_ClearFlag函数的原型

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));

  assert_param(IS_USART_PERIPH_FLAG(USARTx, USART_FLAG)); /* The CTS flag is not available for UART4 and UART5 */   

   

  USARTx->SR = (uint16_t)~USART_FLAG;

}

一目了然,最后USARTx->SR = ~(0100'0000);


再来研究复杂点的USART_ClearITPendingBit函数(注意,这两个函数的第二个参数,是不一样的)


//调用形式

USART_ClearITPendingBit(USART3,USART_IT_TC);

 

//USART_IT_TC的定义

#define USART_IT_TC           ((uint16_t)0x0626)//=0000'0110'0010'0110

 

//USART_ClearITPendingBit的函数原型

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));

  assert_param(IS_USART_PERIPH_IT(USARTx, USART_IT)); /* The CTS interrupt is not available for UART4 and UART5 */

  

  bitpos = USART_IT >> 0x08;                     //=0000'0110

  itmask = (uint16_t)((uint16_t)0x01 << bitpos); //=0100'0000

  USARTx->SR = (uint16_t)~itmask;                //=~(0100'0000)

}

可以看到最后还是USARTx->SR=~(0100'0000);


对比一下USART_ClearFlag和USART_ClearITPendingBit的参数

image.png

USART_ClearFlag的参数 USART_ClearITPendingBit的参数

USART_FLAG_CTS    = 0x0200 USART_IT_CTS   = 0x096A

USART_FLAG_LBD    = 0x0100 USART_IT_LBD    = 0x0846

USART_FLAG_TC      = 0x0040 USART_IT_TC      = 0x0626

USART_FLAG_RXNE = 0x0020 USART_IT_RXNE = 0x0525

这里可以发现一个规律USART_ClearFlag参数只有一个位是“1”,其位置正好等于USART_ClearITPendingBit的参数左移八位后的结果,所以这里可以非常非常肯定的讲:函数USART_ClearFlag和函数USART_ClearITPendingBit的功能totally一样


----------------------------------------------------------------------------------------------------------------------------


涉及内容扩展:

STM32的USART发送数据时如何使用TXE和TC标志


在USART的发送端有2个寄存器,一个是程序可以看到的寄存器——发送数据寄存器(通过USART_DR查看),另一个是程序看不到的寄存器——发送移位寄存器,对应的有两个USART数据发送标志,一个是TXE=发送数据寄存器空,另一个是TC=发送移位寄存器空。

(这粗箭头和这细箭头,简直不要太形象哦,粗箭头是八位八位的传,细箭头是一位一位的传)


    当USART_DR中的数据传送到移位寄存器后,TXE被设置,此时移位寄存器开始向TX信号线按位传输数据,但因为TDR已经变空,所以程序可以把下一个要发送的字节(操作USART_DR)写入TDR中,而不必等到移位寄存器中所有位发送结束,所有位发送结束时(送出停止位后)硬件会设置TC标志。


  另一方面,在刚刚初始化好USART还没有发送任何数据时,也会有TXE标志,因为这时发送数据寄存器是空的。TXEIE和TCIE的意义很简单,TXEIE允许在TXE标志为'1'时产生中断,而TCIE允许在TC标志为'1'时产生中断。


  至于什么时候使用哪个标志,需要根据你的需要自己决定。但我认为TXE允许程序有更充裕的时间填写TDR寄存器,保证发送的数据流不间断。TC可以让程序知道发送结束的确切时间,有利于程序控制外部数据流的时序。

image.png


三种发送方法

1、不开发送完成中断:

/*******************************************************************************

* 函数名  : UART1_SendString

* 描述    : USART1发送字符串

* 输入    : *s字符串指针

* 注释    :0==RESET,表示发送还未完成

USART_FLAG_TC!=RESET,就是=SET,表示发送完成,此时执行USART_GetFlagStatus会把USART_FLAG_TC清零(未证实)

*******************************************************************************/

void UART1_SendString(u8* s)

{

  while(*s)//检测字符串结束符

  {

   //USART_FLAG_TC==RESET时,表示发送还未完成。

    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); 

    USART_SendData(USART1 ,*s++);//发送当前字符

  }

}

2、开中断,额外设置一个标志:

u8 FLAG_TC=0;//定义全局变量

/*******************************************************************************

* 函数名  : UART1_SendString

* 描述    : USART1发送字符串

* 输入    : *s字符串指针

*******************************************************************************/

void UART1_SendString(char* s)

{

  FLAG_TC=0;//提前准备一下

  while(*s)//检测字符串结束符

  {

    USART_SendData(USART1 ,*s++);//发送当前字符

    while( FLAG_TC==0); //0:发送还未完成;1:发送完成

    FLAG_TC=0;

  }

}

 

 

void USART1_IRQHandler(void)

{

  if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)//发送完成中断,= SET

  {

    USART_ClearITPendingBit(USART1,USART_IT_TC);

    FLAG_TC=1;

  }

}

 


开中断时,就不能通过简单的判断标志位USART_FLAG_TC的状态去决定能否发送下一个字符。比方说,使用 


while(*s)

{

 

   USART_SendData(USART1 ,*s++);//发送字符

 

   while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); 

 

   ...

}

执行完发送字符的语句后,因为不可能这么快完成发送,所以程序接下来执行的是while语句。在等待期间,字符发送完毕,这时就会进入到中断,如果在中断里清除标志位,退出中断后,标志位USART_FLAG_TC仍然是RESET;如果不在中断里清除标志位,就不能退出中断。所以程序就会死在while里。


所以这里就需要额外设置一个标志。


3、开中断,数据发送由函数启动,在中断里完成:

//定义全局变量。也可以为了简化,把这四个参数结合起来包含在一个结构体里

u8 TxLength;   //发送数据长度

u8 TxIndicator;//发送指示器,表示目前发送完成哪一位了,下面要发送的是第(TxIndicator+1)位

u8 TxBuff[256];//Data 

u8 TxFnd;      //发送完成标志

     

/*************************************************************************

*程序名称    :   SendFirstByte

*功能        :   启动发送第一个字节

*@Notes     :   鸡贼啊,剩下的都放在USART_FLAG_TC中断里面,因为这个中断是

                 发送完成中断,是利用“发送第一个字节”来“启动发送”

*@Notes     :   需要注意,如果发送结果是乱码的话,一种供参考的解决方案是

                把数据直接赋值给TxBuff,而不要通过函数的形参传递

*输入参数    :   u8 txbuf[]: 需要发送的数据,u8 len : 数据中的字节数

*返回值      :   无

*************************************************************************/

void SendFirstByte( u8 txbuf[], u8 len )

{

TxBuff      = txbuf;//需要发送的数据

TxLength    = len  ;//发送数据长度

TxIndicator = 1    ;//0已经发送,也是用来启动发送的

 

USART_SendData(USART1, txbuf[0]);  /**@Notes:只发送了txbuf的第一个字节*/

}

 

/*************************************************************************

*程序名称    :   USART1_IRQHandler

*功能        :   完成发送数据   

*************************************************************************/

void USART1_IRQHandler(void)

{

if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)

{

USART_ClearITPendingBit(USART1,USART_IT_TC);

if( TxIndicator < TxLength  )//数组的索引max永远小于数组元素的个数

{

USART_SendData(USART1, TxBuff[TxIndicator++]);

}

else//最后一字节数据发送完成

{

TxFnd = 0;

TxIndicator = 0;

}

}

}

USART收发过程中常遇问题总结:

Q:为什么使用USART发送一串字符,最后自接收到了最后一个?

A:是因为发送的间隔太短了,可以在发送每个字符之前先判断一下上一个字符是否发送完成,可以参考上面的“三种发送方法”


Q:为什么使用USART发送一串字符,有时候接收不到第一个字符,有时候又可以接收得到?

A:解决方案是把判断能否发送的语句放在发送数据之前

关键字:USART_ClearITPendingBith  USART_ClearFlag  区别 引用地址:USART_ClearITPendingBith和 USART_ClearFlag的区别

上一篇:stm32串口的flag和it标志位
下一篇:STM32F1x系列——外部中断

推荐阅读最新更新时间:2024-11-10 11:36

人工检测与机器视觉自动检测的区别分析
机器视觉是一门学科技术,广泛应用于生产制造检测等工业领域,用来保证产品质量,控制生产流程,感知环境等。机器视觉系统是将被摄取目标转换成图像信号,传送给专用的图像处理系统,根据像素分布和亮度、颜色等信息,转变成数字化信号;图像系统对这些信号进行各种运算来抽取目标的特征,进而根据判别的结果来控制现场的设备动作。 一、机器视觉优势 机器视觉系统具有高效率、高度自动化的特点,可以实现很高的分辨率精度与速度。机器视觉系统与被检测对象无接触,安全可靠。 人工检测与机器视觉自动检测的主要区别有: 二 、案例 为了更好地理解机器视觉,下面,我们来介绍在具体应用中的几种案例。 01 啤酒厂采用的填充液位检测系统为例 当每个啤酒瓶移动经过
[嵌入式]
人工检测与机器视觉自动检测的<font color='red'>区别</font>分析
热力膨胀阀的分类及有什么区别_热力膨胀阀怎么调节
本文以热力膨胀阀为中心,主要介绍了什么是热力膨胀阀,热力膨胀阀的结构、作用与工作原理。详细的说明了热力膨胀阀的分类及区别分析。最后说明了热力膨胀阀的调节技巧与禁忌。 什么是热力膨胀阀 热力膨胀阀是组成制冷装置的重要部件,通过控制蒸发器出口气态制冷剂的过热度来控制进入蒸发器的制冷剂流量是制冷系统中四个基本设备之一。 热力膨胀阀结构 热力膨胀阀由温度传感元件、执行机构和调节机构3部分组成。下图所示是内平衡式热力膨胀阀的外形与内部结构。 热力膨胀阀的作用 热力膨胀阀又称温度调节阀,在制冷系统中,热力膨胀阀装在蒸发器进液口的供液管道上,具有三个方面的作用: ①节流降压 将冷凝器冷凝后的高温高压制冷剂节流降压
[测试测量]
变频器滤波器与电抗器有什么区别
随着现代工业技术的发展,越来越多的机械设备开始采用变频器来实现调速功能。因此,在变频器的起伏调节和增强设备性能方面,需要一些辅助设备来帮助变频器实现更好的性能。这里,我们将讨论其中两个重要的设备——变频器滤波器和电抗器之间的区别。 1.定义 变频器滤波器和电抗器主要用于防止变频器对交流电源产生损害,对减少电磁干扰,提高传输效率起到了重要作用。但是,它们之间的作用却有所不同。 变频器滤波器是变频器用于减少电流谐波和噪声的滤波器。它们将传输到变频器之前的电源电压进行滤波,使其变得更加平滑。其目的是抑制交流阶段电压和电流中的谐波,确保其他设备不受到干扰,并且确保变频器的正常运行。 电抗器是一种电学元器件。它的作用是为了限制电流量,从而平
[嵌入式]
标签与信标的区别是什么?
作者:Dialog公司产品营销经理 同伟 蓝牙技术的快速演变使有些人会困惑这种无线电系统是如何在标签(tag)和信标(beacon)中应用的。 可以这么说,无线电标记(tagging)的想法是随着短距离被动式RFID标签而出现的。标签在扫描仪接近时,会提供一个简单无线编码作为回应,扫描仪也可由此判断并显示传输信号的强度。扫描仪大多是工业装置,但随着智能手机变得更加流行,智能电子海报或广告牌的想法开始出现。这类显示屏有一个嵌入式RFID标签,当使用者走近电子海报或广告牌,可以通过一个关联应用程序(通过手机接入互联网),在显示屏上查看更多信息。被动标签不需要电池,访问代码允许该应用访问各种数据 如实时旅行信息(
[物联网]
标签与信标的<font color='red'>区别</font>是什么?
ARM7与ARM9的区别以及ARM,FPGA,DSP的特点和区别是什么?
一.谈谈ARM7与ARM9的区别: 本文是写给准备学习ARM技术,而又没想好要学ARM7还是ARM9或者对ARM7与ARM9的区别不是很了解的初学者。希望本文对你们有点用处。 由于职业的关系,经常会回答一些ARM初学者的问题,虽然问题千奇百怪,但以下两个问题绝对很有代表性。 ARM7和ARM9的都有些什么区别? 我准备学ARM,但不知是选ARM7还是ARM9好? 也许这些问题在大虾们的眼里已不是问题,但对于初学者确实很具必要弄清楚。先说下:ARM7和ARM9的区别。 1.时钟频率的提高 虽然ARM7和ARM9内核架构相同,但ARM7处理器采用3级流水线的冯·诺伊曼结构;,而ARM9采用5级流水线的哈佛结构。增加的流水线设计提高了
[单片机]
交流耐压测试和直流耐压测试的区别
耐压测试( Withstanding Voltage Test )又称作高压测试( Hipot Test )或介电强度测试( Dielectric Test ),可能是大家熟悉和在产品流程安全测试中用的最多的。 耐压测试是一种无破坏性的测试,它用来检测经常发生的瞬态高压下产品的绝缘能力是否合格。它在一定时间内施加高压到被测试设备以确保设备的绝缘性能足够强。 测试电压,大部分的安全标准允许在耐压测试中使用交流或直流电压。若使用交流测试电压,当达到电压峰值时,无论是正极性还是负极性峰值时,待测绝缘体都承受zui大压力。因此,如果决定选择使用直流电压测试,就必须确保直流测试电压是交流测试电压的 倍,这样直流电压才可以与交流电压峰
[测试测量]
LABVIEW和LABWINDOWS区别
labwindows cvi 与 labview 区别 ==================================================================================== 修改时间 07-19-2009 03:16 AM NI的工程师你们好: labview与lab windows cvi 都是贵公司的产品吧,他们之间有什么联系或者区别呢? LabVIEW is a graphical programming language. It is made up of a user interface which
[测试测量]
单片机与嵌入式系统有什么区别与联系
  随着电子信息科学技术信息化,智能化,网络化的发展,单片机与嵌入式也获得了广阔的应用空间。本文简单分析了单片机与嵌入式系统的联系、组成结构对比等基础知识,并列举了几种适用于PIC18F系列单片机的几种嵌入式实时操作系统。   单片机与嵌入式系统组成结构对比   (1)单片机基本结构   单片机由运算器、控制器、存储器、输入输出设备构成。   (2)嵌入式系统成部分:   嵌入式系统一般由以下几组嵌入式微处理器、外围硬件设备、嵌入式操作系统、特定的应用程序。   嵌入式系统设计的第一步是结合具体的应用,综合考虑系统对成本、性能、可扩展性、开发周期等各个方面的要求,确定系统的主控器件,并以之为核心搭建系统硬件平台。   单
[单片机]
单片机与嵌入式系统有什么<font color='red'>区别</font>与联系
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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