完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1、IIC定义
IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司(后被NXP收购)在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。多主多从的通讯协议。 下文将结合NXP官方的IIC手册讲解IIC协议。下载链接见文末。 I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。速率最高400Kbit/s。 在1998年的修订中增加了高速模式,速率高达3.4Mbit/s。(这里不讲,只说快速模式)。 2、IIC协议规范 2.1 SDA和SCL信号 连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能,当总线空 闲时这两条线路都是高电平。SDA 和SCL 都是双向线路都通过一个电流源或上拉电阻连接到正的电源电压。一般情况下我们都采用上拉电阻的方式 2.2 数据有效性 在SCL高电平的时候采样,也就是有效。低电平的时候切换数据 2.3 开始和结束信号 起始条件:SCL线是高电平时,SDA线从高电平向低电平切换。 停止条件:SCL线是高电平时,SDA线从低电平向高电平切换。 动画展示启动信号 代码实现 void I2C_Start(void) { //IO输出 SDA_OUT(); SCL_OUT(); I2C_DELAY(); //IO置高 SDA_SET(); SCL_SET(); //延时 I2C_DELAY(); //为低 SDA_CLR(); I2C_DELAY(); I2C_DELAY(); SCL_CLR(); } 结束信号时类似的方式(不是动图) 代码实现 void I2C_Stop(void) { //IO输出 SDA_OUT(); SCL_OUT(); //IO置0 SDA_CLR(); SCL_CLR(); I2C_DELAY(); SCL_SET(); //延时 I2C_DELAY(); I2C_DELAY(); I2C_DELAY(); //SDA置1 SDA_SET(); I2C_DELAY(); I2C_DELAY(); } 2.4 字节格式 SDA数据线上的每个字节必须是8位,每次传输的字节数量没有限制。每个字节后必须跟一个响应位(ACK)。首先传输的数据是最高位(MSB),SDA上的数据必须在SCL高电平周期时保持稳定,数据的高低电平翻转变化发生在SCL低电平时期。 每一个字节后面跟着一个ACK,有ACK就可以继续写或读。NACK,就停止 ACK:主机释放总线,传输完字节最后1位后的SCL的高电处,从机拉低电平。 NACK:主机释放总线,传输完字节最后1位后的SCL的高电处,从机无响应,总线为高电平。 动画描述写入的过程 代码实现 uint8_t I2C_Send_byte(uint8_t data) { uint8_t k; //发送8bit数据 for(k=0;k《8;k++){ I2C_DELAY(); if(data&0x80){ SDA_SET(); } else{ SDA_CLR(); } data=data《《1; I2C_DELAY(); SCL_SET(); I2C_DELAY(); I2C_DELAY(); SCL_CLR(); } //延时读取ACK响应 I2C_DELAY(); SDA_SET(); //置为输入线 SDA_IN(); I2C_DELAY(); SCL_SET(); I2C_DELAY(); //这里出现了问题,延时变的无限大 //读数据 k=SDA_READ(); if(k){ NACK响应 return 0; } I2C_DELAY(); SCL_CLR(); I2C_DELAY(); SDA_OUT(); if(k){ NACK响应 return 0; } return 1; } uint8_t I2C_Receive_byte(uint8_t flg) { uint8_t k,data; //接收8bit数据 //置为输入线 SDA_IN(); data=0; for(k=0;k《8;k++){ I2C_DELAY(); SCL_SET(); I2C_DELAY(); //读数据 data=data |SDA_READ(); data=data《《1; I2C_DELAY(); SCL_CLR(); I2C_DELAY(); } data=data》》1; //往回移动1次 //返回ACK响应 //置为输出线 SDA_OUT(); if(flg){ SDA_SET(); //输出1-NACK }else{ SDA_CLR();//输出0-ACK } I2C_DELAY(); SCL_SET(); I2C_DELAY(); I2C_DELAY(); SCL_CLR(); I2C_DELAY(); SDA_OUT(); //返回读取的数据 return (uint8_t)data; } 2.5 从机地址和读写位 开始信号—》地址—》读写位—》ACK—》数据—》ACK.。..。..。..。..—》停止位 这里只说7位地址,前7位为地址,最后一位为读写位,1表示读操作,0表示写操作 主机发给从机数据,也就是写,没有数据转向时 主机立即读从机数据,从第一个字节 (Combined)综合数据格式 3、计算IIC的频率 通信频率由主机掌控,也就是代码中的延时函数决定的 从上面,我们得知最高速为400Kbit/s。我们设计300Kbit/s。 速率300Kbit/s,对应周期1/300ms=10/3us≈3us,4分频就是3/4us。 我们使用的延时是,1/120MHZ*3*30 =3/4us 也就是频率是300Kbit/s 和SPI类似,时钟下降沿时,数据转换,时钟上升沿时,采样数据。也就是时钟高电平数据有效。 /*120Mhz时钟时,当ulCount为1时,函数耗时3个时钟,延时=3*1/120us=1/40us*/ /* SystemCoreClock=120000000 us级延时,延时n微秒 SysCtlDelay(n*(SystemCoreClock/3000000)); ms级延时,延时n毫秒 SysCtlDelay(n*(SystemCoreClock/3000)); m级延时,延时n秒 SysCtlDelay(n*(SystemCoreClock/3)); */ #if defined (__CC_ARM) /*!《 ARM Compiler */ __asm void SysCtlDelay(unsigned long ulCount) { subs r0, #1; bne SysCtlDelay; bx lr; } #elif defined ( __ICCARM__ ) /*!《 IAR Compiler */ void SysCtlDelay(unsigned long ulCount) { __asm(“ subs r0, #1n” “ bne.n SysCtlDelayn” “ bx lr”); } #elif defined (__GNUC__) /*!《 GNU Compiler */ void __attribute__((naked)) SysCtlDelay(unsigned long ulCount) { __asm(“ subs r0, #1n” “ bne SysCtlDelayn” “ bx lr”); } #elif defined (__TASKING__) /*!《 TASKING Compiler */ /*无*/ #endif /* __CC_ARM */ /* * @brief SysCtlDelay * @param ulCount 延时值,必须大于0 * @retval None */ void SysCtlDelay_IIC(unsigned long ulCount) { SysCtlDelay(ulCount); } /定义时钟频率,300KHz #define I2C_DELAY() SysCtlDelay_IIC(30) 4、PCF8536 4.1 Acknowledge 这个地方能看到关于2.4节关于ACK和NACk的说明 。 4.2 Addressing 这里直接给出读地址和写地址,也就是最后一位的区别 4.3 读写时序 其实就是按照IIC协议的 读指定器件的指定寄存器 主机设置完寄存器地址之后,再去读写 注意:读取多个字节,最后一个字节的回包应该是NACK 主机立即从机第一个字节读取 注意:读取多个字节,最后一个字节的回包应该是NACK |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1618 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1545 浏览 1 评论
979 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1597 浏览 2 评论
1864浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
647浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
533浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 02:36 , Processed in 0.907847 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号