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

函数定义如下:

 ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
uint32_t lastevent = ;
uint32_t flag1 = , flag2 = ;
ErrorStatus status = ERROR; /* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_EVENT(I2C_EVENT)); /* Read the I2Cx status register */
flag1 = I2Cx->SR1;
flag2 = I2Cx->SR2;
flag2 = flag2 << ; /* Get the last event value from I2C status register */
lastevent = (flag1 | flag2) & FLAG_Mask; /* Check whether the last event contains the I2C_EVENT */
if ((lastevent & I2C_EVENT) == I2C_EVENT)
{
/* SUCCESS: last event is equal to I2C_EVENT */
status = SUCCESS;
}
else
{
/* ERROR: last event is different from I2C_EVENT */
status = ERROR;
}
/* Return status */
return status;
}

该函数第一个参数是输入需要检查的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事件,事件名称及定义如下:

/*I2C_EVENT_MASTER_MODE_SELECT                          : EV5*/
#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ /*I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6 */
#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR and TRA flags */
/*I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6*/
#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ /*I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8*/
#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
/*I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2*/
#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. 为什么360、百度、腾讯出的Mac端云盘客户端都只有同步盘?(用户量小,同步盘开发成本低,Linux下都没有客户端)

    如题,顾名思义,同步盘是用来同步的,不具备增量的功能,像这三家在Windows端出的客户端都是即有同步也有增量的. 陆续出来的,可能大家更多的是跟随策略,不得不提dropbox是这样的形式.mac电脑 ...

  2. 为javasript中对象与json串之间转换的总结。

    jQuery.json 是 jQuery 的一个插件,可轻松实现对象和 JSON 字符串之间的转换.可序列化 JavaScript 对象.数值.字符串和数组到 JSON 字符串,同时可转换 JSON ...

  3. MongoDB自学日记1——基本操作

    作为一个做底层及后台研发的,最近对NoSQL却产生了浓厚的兴趣,加入了一个DBA群,据说北京排的上号的DBA都在里面,然而里面基本都是Oracle系的,MySQL和MongoDB系的少之又少.学习靠不 ...

  4. LeetCode : Given a string, find the length of the longest serial substring without repeating characters.

    Given a string, find the length of the longest serial substring without repeating characters. Exampl ...

  5. chrome和safari字体粗细问题

    因为我用的是mac电脑,写项目所遇到的问题,这也是我上网和手动试了多次,觉得有效,分享给大家 -webkit-font-smoothing: subpixel-antialiased; -webkit ...

  6. redis连接错误3种解决方案System Error MISCONF Redis is configured to save RDB snapshots

    redis连接错误System Error MISCONF Redis is configured to save RDB snapshots, but XX   情况1解决办法: 由于强制停止red ...

  7. 直播技术:从性能参数到业务大数据,浅谈直播CDN服务监控

    线上服务的有效监控和数据收集,一直是后端服务离不开的话题.直播作为一种经典的分布式系统,监控以及数据收集更是必不可少的工作.如何对海量的服务集群有效的监控和保活,又如何抓取集群中的碎片数据中来优化服务 ...

  8. spring 5.x 系列第20篇 ——spring简单邮件、附件邮件、内嵌资源邮件、模板邮件发送 (代码配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 邮件发送配置类为com.heibaiyin ...

  9. .netcore Control调用View方法

    控制器代码如下: 视图代码如下: 完整项目代码参考网址:https://github.com/gamecc666/BackTipFrontProject 版权声明:本文为博主原创文章,如需转载,请标明 ...

  10. leetcode的Hot100系列--461. 汉明距离

    求两个数的二进制位不同的位置,最先想到的就是异或操作, 异或:按位运算,相同为0,不同为1. 比如: a = 6 对应的二进制表示为: 0 0 1 1 1 ​ b = 9 对应的二进制表示为: 0 1 ...