STM32里I2C_CheckEvent函数我们应该是相当熟悉了,在每次发送数据后我们都需要检验相应的EVx(x = 0,1,2,,,)事件是否有发送。

函数定义如下:

  1. ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
  2. {
  3. uint32_t lastevent = ;
  4. uint32_t flag1 = , flag2 = ;
  5. ErrorStatus status = ERROR;
  6.  
  7. /* Check the parameters */
  8. assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  9. assert_param(IS_I2C_EVENT(I2C_EVENT));
  10.  
  11. /* Read the I2Cx status register */
  12. flag1 = I2Cx->SR1;
  13. flag2 = I2Cx->SR2;
  14. flag2 = flag2 << ;
  15.  
  16. /* Get the last event value from I2C status register */
  17. lastevent = (flag1 | flag2) & FLAG_Mask;
  18.  
  19. /* Check whether the last event contains the I2C_EVENT */
  20. if ((lastevent & I2C_EVENT) == I2C_EVENT)
  21. {
  22. /* SUCCESS: last event is equal to I2C_EVENT */
  23. status = SUCCESS;
  24. }
  25. else
  26. {
  27. /* ERROR: last event is different from I2C_EVENT */
  28. status = ERROR;
  29. }
  30. /* Return status */
  31. return status;
  32. }

该函数第一个参数是输入需要检查的I2Cx(x = 1,2,3,4,5)外设,第二个参数是检查的事件,如下所示:

I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED :       EV1
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED :         EV1
I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED :     EV1
I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED :       EV1
I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED :         EV1
I2C_EVENT_SLAVE_BYTE_RECEIVED :                 EV2
(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) :       EV2
(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) :       EV2
I2C_EVENT_SLAVE_BYTE_TRANSMITTED :               EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) :     EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) :      EV3
I2C_EVENT_SLAVE_ACK_FAILURE :                   EV3_2
I2C_EVENT_SLAVE_STOP_DETECTED :                 EV4
I2C_EVENT_MASTER_MODE_SELECT :                 EV5
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED :        EV6 
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED :        EV6
I2C_EVENT_MASTER_BYTE_RECEIVED :              EV7
I2C_EVENT_MASTER_BYTE_TRANSMITTING :            EV8
I2C_EVENT_MASTER_BYTE_TRANSMITTED :             EV8_2
I2C_EVENT_MASTER_MODE_ADDRESS10 :               EV9

本文就举里面常用的一些事件为例,来分析该函数为什么能够自动清除标志位。包含EV5,EV6,EV8以及EV7事件。

在使用I2C发送数据时我们会用到EV5,EV6,EV8事件,事件名称及定义如下:

  1. /*I2C_EVENT_MASTER_MODE_SELECT : EV5*/
  2. #define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */
  3.  
  4. /*I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6 */
  5. #define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR and TRA flags */
  6. /*I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6*/
  7. #define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */
  8.  
  9. /*I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8*/
  10. #define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
  11. /*I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2*/
  12. #define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */
  • 根据I2C_CheckEvent函数的定义,事件的高16位为I2C外设的SR2寄存器,低16位为I2C外设的SR1寄存器。
  • 先来看看 I2C_EVENT_MASTER_MODE_SELECT,宏定义为,0x00030001,对应的SR1和SR2寄存器如下所示:

其中MSL为1表为主模式,BUSY为1表总线忙碌,

这两位一般都是在产生STOP信号的时候置0,其他时候都为1。

看看SB位如何清零,

我们在Check_Event函数里面读取了SR1寄存器,我们在发送了起始信号之后就需要发送设备地址进行访问,在I2C_Send7bitAddress函数里面我们访问了数据寄存器SD,于是在下一次检测标志位之前SB被清除。

  • 再来看看两个EV6事件 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 和 I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED,这两者的区别就是一个用于发送模式,另一个用于接受模式,发送模式为0x00070082,

TRA数据单元一般产生STOP信号后清除,至于ADDR位,在I2C_CheckEvent函数里面,我们是顺序地读取了SR1和SR2寄存器,于是ADDR位被清除。对于TxE位,我们下一步能会进行数据发送操作,也就是使用I2C_SendData函数访问DR数据寄存器,于是TxE也被清除。

  • 还有一个EV8事件 I2C_EVENT_MASTER_BYTE_TRANSMITTED, 定义为0x00070084,

此处只讨论BTF位的清除,

也是访问SR1寄存器和对数据寄存器的读或写可以清除该位,因此BTF位也被清除。

至于I2C_CheckEvent里面其他事件所设计的位清除,我就不一一举例了,可以按照这个思路,参考STM32F10x-中文参考手册自己一步步的查看。

I2C_ChencEvent比I2C_GetFlagStatus函数好的一点就是它检测了与事件相关的所有寄存器位,而后者只检测提供的标志位。

STM32-I2C_CheckEvent-标志位自动清除理解的更多相关文章

  1. stm32串口——标志位学习

    /* 在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器,另一个是程序看不到的移位寄存器,对应USART数据发送有两个标志,一个是TXE=发送数据寄存器空,另一个是TC=发送 ...

  2. STM32的RTC中断标志只能手动清除

    背景: 最近在做一个stm32的项目,其中用到RTC的实时时钟功能.时钟源采用外部32.768K晶振,时钟预分频设置为32767,目的是为了产生1秒的中断,然后在中断处理函数中更新实时年月日时分秒. ...

  3. STM32 串口固件库中定义的几个中断标志位什么意思?

    在stm32f10x_usart.h中以上几个宏,很没有规律,诈一看还真不知道为什么会这么定义,其实通过代码就很容易明白: D7~D5:代表中断标志位对应的中断使能位在 CR1.CR2还是CR3寄存器 ...

  4. 汇编语言标志位 含义 NV UP EI NG NZ AC PE CY

    缩写原意: Overflow of = OV NV [No Overflow] Direction df = DN (decrement) UP (increment) Interrupt if = ...

  5. 【.net程序破解】实战之标志位破解绕过注册法

    今天有时间玩了下一个不错的软件Advanced System Cleaner,可惜要注册 于是想办法给破解了,这是跟之前不同的地方,属于.NET破解教程: 软件地址 - http://www.crsk ...

  6. 嵌入式单片机,ATmega328P,外部中断INT0,INT1,INT2,中断标志位介绍

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  7. 从点击Button到弹出一个MessageBox, 背后发生了什么(每个UI线程都有一个ThreadInfo结构, 里面包含4个队列和一些标志位)

    思考一个最简单的程序行为:我们的Dialog上有一个Button, 当用户用鼠标点击这个Button时, 我们弹出一个MessageBox.   这个看似简单的行为, 谁能说清楚它是如何运行起来的,背 ...

  8. python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义

    本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...

  9. 汇编 OD 标志位 置位相关指令

    知识点: l 标志位 置位相关指令   l 标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW)    标志寄存器PSW是一个16为的寄存器.它反映了CPU运算的状态特征并且存放某些控制标志. ...

随机推荐

  1. PowerShell将Windows store应用程序安装为开发者模式

    原文: PowerShell将Windows store应用程序安装为开发者模式 在本地部署Windows 商店应用程序时,我们会遇到Add-AppDevPackage.ps1脚本,这个脚本和所在安装 ...

  2. 该内存不能read 或written数值 叙述(居然还有具体的讲究)

    该内存不能read 或written数值 叙述 0 0x0000 作业完成. 1 0x0001 不正确的函数. 2 0x0002 系统找不到指定的档案. 3 0x0003 系统找不到指定的路径. 4 ...

  3. [java代码库]-简易计算器(第一种)

    简易计算器(效果如图所示) 第一种方案:采用Javascript+html完成计算器,支持+-*/,结果显示不允许使用input输入域(可以考虑使用<span>) <html> ...

  4. Linux中同步互斥机制研究之原子操作

    操作系统中,对共享资源的访问需要有同步互斥机制来保证其逻辑的正确性,而这一切的基础便是原子操作. | 原子操作(Atomic Operations):    原子操作从定义上理解,应当是类似原子的,不 ...

  5. Arcgis Server 10.4.1 搭建集群环境

    1.准备工作 Arcgis Server 10.4.1  以及许可一枚 共享存储(通过UNC路径访问,如"\\server1\arcgisserver\") 服务器两台(虚拟机也可 ...

  6. 程序代写, CS代写, 代码代写, CS编程代写, java代写, python代写, c++/c代写, R代写, 算法代写, web代写

    互联网一线工程师程序代写 微信联系 当天完成 查看大牛简介特色: 学霸代写,按时交付,保证原创,7*24在线服务,可加急.用心代写/辅导/帮助客户CS作业. 客户反馈与评价 服务质量:保证honor ...

  7. Dynamics 365 for sales - Account与Contact之间的关系

    Account :可以理解成客户,可以是公司组织,当然也可以是个人 Contact: 从字面理解为联系人 例如,腾讯公司要买我们公司的软件,他们的主要负责人是IT部门的小马,那么,腾讯要创建成Acco ...

  8. Django之forms组件进阶

    Django Form表单组件   Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要 ...

  9. 推荐一个高效,易用功能强大的可视化API管理平台

    项目管理 提供基本的项目分组,项目管理,接口管理功能 接口管理 友好的接口文档,基于websocket的多人协作接口编辑功能和类postman测试工具,让多人协作成倍提升开发效率 MockServer ...

  10. idea初见问题整理_错误: -source 1.5 中不支持 diamond 运算符

    最近在移动工程到idea下,顺便改目录结构,遇到的问题不一定全部记录,有些答案摘抄自别人博客,已注明来源,由于不是摘抄自同一作者,且有自己的一些内容,所以标注为原创. 1.(错误: -source 1 ...