完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
ST单片机的I2C总线操作分为主机模式与从机模式。做主机时,由主机提供时钟驱动。在通讯的过程中相关的硬件寄存器会根据某些事件的发生而置位。这样通信的双方就可以根据这些事件标志来控制通信的过程。在实际程序中有两种用法,一种是阻塞式的等待查询法。这种方式下通信过程是在不停地检查各种特定事件的过程中完成的。还有一种是中断处理法,I2C硬件在工作时会产生中断,应用程序在中断处理程序里检查各种硬件中断标志来完成通信过程。下文主要来源于ST的官方标准库文件stm8l10x_i2c.h
I2C主机模式下的事件(按通信流程顺序描述) 通讯开始时的EV5 在主机发送开始信号START(I2C_GenerateSTART()函数)之后必须等待EV5事件。此事件出现意味着可以在I2C总线上开始通讯(总线是空闲状态)该时间完成标志在库文件中被定义为: I2C_EVENT_MASTER_MODE_SELECT = (uint16_t)0x0301 从机确认地址的EV6 在检查EV5后,主机发送从机地址(使用I2C_Send7bitAddress()函数),这个函数还确定本次通信的方向:做发送端或是接收端 然后主机必须等待从机设备发出确认信号ACK。 如果确认信号出现,那么: 1)如果是主机作接收端(7位地址) 那么会是I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED标志被触发。 2)如果是主机作发送端(7位地址) 那么会是I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED标志被触发。 3)在10位寻址模式下,主机在发出SRART信号并且检查EV5事件后必须发送10位寻址模式的地址头部分(使用I2C_SendData()) 然后主机应该等待EV9事件。EV9事件出现意味着10位寻址模式下的地址头部已经被正确地发送到了总线上。然后,主机应当发送10位地址模式下的地址尾部LSB(使用I2C_Send7bitAddress()).然后主机等待EV6事件; EV6 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED = (uint16_t)0x0782 I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED = (uint16_t)0x0302 EV9(10位地址模式下才会出现) I2C_EVENT_MASTER_MODE_ADDRESS10 = (uint16_t)0x0308 通信过程中的事件: 如果通信已经建立,主机就要开始检查以下事件 1)如果是主机接收模式:主机必须要等待EV7事件,然后接收从机发来的数据(I2C_ReceiveData() function) 2)如果是主机发送模式:主机要马上发送数据(I2C_SendData()),然后等待事件EV8或EV8_2 EV8和EV8_2事件非常相似,但有以下不同: -EV8事件意味着要发送的数据已经被写入到了数据寄存器,正在逐次进入物理发送器。 -EV8_2事件意味着数据已经确实进入了物理发送器,并且出现在了总线上。 在大多数情况下,使用EV8已经足够了。如果同时还要检查EV8_2事件会导致通信过程变慢,但是这样可以使通信过程有更高的可信度。EV8_2也比EV8更合适用来检查最后一部分数据是否已经成功发送(在STOP信号前的最后数据) 要注意的是,如果我们的软件不能确认最后的字节结尾已经被发送。那我们可以通过同时检查EV7事件和BTF标志(比如. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF))来确认这一点。不过在这种情况下通信会变慢。 EV7: I2C_EVENT_MASTER_BYTE_RECEIVED = (uint16_t)0x0340 主机发送模式: EV8: I2C_EVENT_MASTER_BYTE_TRANSMITTING = (uint16_t)0x0780 EV8_2 I2C_EVENT_MASTER_BYTE_TRANSMITTED = (uint16_t)0x0784 ********************************************************************************************************************************* I2C从机模式下的事件(按照通信过程描述) 通信开始时的事件 首先,单片机作从机时要通过I2C_AcknowledgeConfig()函数使能自己的应答模式。另外要设置自己的通信地址。这个地址在I2C_OwnAddress1字段中。 主机发送了开始信号START并跟随发送了从器件地址后,从机会检查地址是否与自己匹配。如果匹配则会发送一个ACK信号: 1)在一般情况下当主机发送的地址和自己的地址匹配时会出现EV1事件 I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED xxx会是TRANSMITTER或RECEIVER: I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED 2)如果主机发送的是统一呼叫(发送地址是0x00),并且从机使用函数I2C_GeneralCallCmd()使能了统一呼叫应答。那么也会出现EV1事件 I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED EV1: 一般情况下: I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED = (uint16_t)0x0202 I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED = (uint16_t)0x0682 统一呼叫情况下: I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED = (uint16_t)0x1200 在EV1事件出现后: 如果是从机接收模式: EV2: 收到字节数据. I2C_EVENT_SLAVE_BYTE_RECEIVED = (uint16_t)0x0240 EV4:通信结束(主机发送一个停止信号STOP终止通信). I2C_EVENT_SLAVE_STOP_DETECTED = (uint16_t)0x0010 从机发送模式下: EV3:从机发送完毕一个字节数据: I2C_EVENT_SLAVE_BYTE_TRANSMITTED = (uint16_t)0x0684 I2C_EVENT_SLAVE_BYTE_TRANSMITTING = (uint16_t)0x0680 EV3_2:主机发送了NACK信号,之后从机就等待主机发送STOP信号也就是EV4事件; I2C_EVENT_SLAVE_ACK_FAILURE = (uint16_t)0x0004 接收模式下事件I2C_EVENT_SLAVE_BYTE_TRANSMITTED和I2C_EVENT_SLAVE_BYTE_TRANSMITTING功能很接近.I2C_EVENT_SLAVE_BYTE_TRANSMITTING事件检测是可选的。用于确认EV3事件发生时数据传输正确完成。 正常通信时的时序: |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 00:14 , Processed in 1.233612 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号