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
上一篇:TQ210_裸机编程(二)——按键控制LED灯
下一篇:STM32 SPI详解
推荐阅读最新更新时间:2024-11-10 16:09
设计资源 培训 开发板 精华推荐
- WGM110参考设计文件
- FXO/DAA 设计使用 Clare OptoMOS 组件,用于 TBR-21 型 DAA 以及使用 IAA110P 的计量滤波器
- EVAL-AD7843EBZ,用于评估 AD7843 电阻式触摸屏控制器的评估板
- 在移动应用中使用 MMA73x0L 与低 G 单元连接模拟加速度计
- 使用 ROHM Semiconductor 的 BD46411 的参考设计
- ADA4610-2ARMZ-RL等效前置放大光电二极管电路典型应用电路
- BD48K54电压检测IC在BD48xxx系列中的典型应用
- MIC23451 的典型应用:具有超轻负载和电源良好的 3MHz、2A 三重同步降压稳压器
- LT8631HFE 400kHz、3.3V、1A 降压转换器的典型应用电路
- LT3692AIFE 四路输出 5V、2.5V、1.8V 和 1.2V 多频同步、两级转换器的典型应用电路