这篇文章主要介绍了STM32 IIC是什么意思,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
创新互联网站建设公司是一家服务多年做网站建设策划设计制作的公司,为广大用户提供了网站建设、成都网站制作,成都网站设计,广告投放平台,成都做网站选创新互联,贴合企业需求,高性价比,满足客户不同层次的需求一站式服务欢迎致电。
IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司(后被NXP收购)在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。多主多从的通讯协议。
下文将结合NXP官方的IIC手册讲解IIC协议。下载链接见文末。
I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。速率最高400Kbit/s。
起始条件: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(); }
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; }
这里只说7位地址,前7位为地址,最后一位为读写位,1表示读操作,0表示写操作
主机立即读从机数据,从第一个字节
通信频率由主机掌控,也就是代码中的延时函数决定的
从上面,我们得知最高速为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, #1\n" " bne.n SysCtlDelay\n" " bx lr"); } #elif defined (__GNUC__) /*!< GNU Compiler */ void __attribute__((naked)) SysCtlDelay(unsigned long ulCount) { __asm(" subs r0, #1\n" " bne SysCtlDelay\n" " 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)
感谢你能够认真阅读完这篇文章,希望小编分享的“STM32 IIC是什么意思”这篇文章对大家有帮助,同时也希望大家多多支持创新互联,关注创新互联行业资讯频道,更多相关知识等着你来学习!