I2C总线及单片机模拟I2C总线通信程序编写
来源:互联网 发布:日本推理小说 知乎 编辑:程序博客网 时间:2024/05/05 19:46
1、I2C总线
I2C总线是Inter-IntegratedCircuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。
I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
2、数据有效性、起始和终止信号
数据位的有效性:I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
起始信号:SCL线为高电平期间,SDA线由高电平向低电平的变化;
终止信号:SCL线为高电平期间,SDA线由低电平向高电平的变化。
起始信号和终止信号都由主机发出。
3、数据传送格式
1)字节传送与应答
每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据。
I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。
在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)。
每次数据传送总是由主机产生的终止信号结束。
若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。
在总线的一次数据传送过程中,可以有以下几种组合方式:
a、主机向从机发送数据,数据传送方向在整个传送过程中不变:
注:有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。
A表示应答, A非表示非应答(高电平)。S表示起始信号,P表示终止信号。
b、主机在第一个字节后,立即从从机读数据
c、在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读/写方向位正好反相。
Void I2CStart(void){ SDA = 1;SomeNop( );SCL = 1;SomeNop( );SDA = 0;SomeNop( );//自己定义的子函数,延时大于4us;}
void I2cStop(void){SDA = 0;SomeNop( );SCL = 1;SomeNop( );SDA = 1;SomeNop( );}3)写一个字节操作
bit I2CWrite(unsigned char dat) //I2C总线写操作,待写入字节dat,返回值为应答状态{ bit ack; //用于暂存应答位的值 unsigned char mask; //用于探测字节内某一位值的掩码变量 for (mask=0x80; mask!=0; mask>>=1) //从高位到低位依次进行 { if ((mask&dat) == 0) //该位的值输出到SDA上 I2C_SDA = 0; else I2C_SDA = 1; I2CDelay(); I2C_SCL = 1; //拉高SCL I2CDelay(); I2C_SCL = 0; //再拉低SCL,完成一个位周期 } I2C_SDA = 1; //8位数据发送完后,主机释放SDA,以检测从机应答 I2CDelay(); I2C_SCL = 1; //拉高SCL ack = I2C_SDA; //读取此时的SDA值,即为从机的应答值 I2CDelay(); I2C_SCL = 0; //再拉低SCL完成应答位,并保持住总线 return (~ack); //应答值取反以符合通常的逻辑:0=不存在或忙或写入失败,1=存在且空闲或写入成功}4)读一个字节操作
unsigned char I2CReadACK() //I2C总线读操作,并发送应答信号,返回值为读到的字节{ unsigned char mask; unsigned char dat; I2C_SDA = 1; //首先确保主机释放SDA for (mask=0x80; mask!=0; mask>>=1) //从高位到低位依次进行 { I2CDelay(); I2C_SCL = 1; //拉高SCL if(I2C_SDA == 0) //读取SDA的值 dat &= ~mask; //为0时,dat中对应位清零 else dat |= mask; //为1时,dat中对应位置1 I2CDelay(); I2C_SCL = 0; //再拉低SCL,以使从机发送出下一位 } I2C_SDA = 0; //8位数据发送完后,拉低SDA,发送应答信号 I2CDelay(); I2C_SCL = 1; //拉高SCL I2CDelay(); I2C_SCL = 0; //再拉低SCL完成应答位,并保持住总线 return dat;}
- I2C总线及单片机模拟I2C总线通信程序编写
- 标准80C51单片机模拟I2C总线的主机程序
- 标准AVR单片机模拟I2C总线的主机程序
- 使用GPIO模拟I2C总线进行通信
- 使用GPIO模拟I2C总线进行通信
- 使用GPIO模拟I2C总线进行通信
- 使用GPIO模拟I2C总线进行通信
- 使用GPIO模拟I2C总线进行通信
- 使用GPIO模拟I2C总线进行通信
- 单片机模拟I2C总线及24C02(I2C EEPROM)读写实例(源代码)
- I2C总线通信
- I2C总线及总线阻塞
- i2c总线测试程序
- I2C总线概要及用GPIO模拟I2C
- 51单片机I2C总线代码
- 51单片机I2C总线驱动程序
- 51单片机模拟I2C总线的C语言实现
- 51单片机模拟I2C总线的C语言实现
- 第一次写博客
- mysql学习(二)
- php实现一种简单的加权均衡算法
- 专门为Github党打造的超级无敌Chrome插件
- 二叉排序树
- I2C总线及单片机模拟I2C总线通信程序编写
- mac下查看隐藏文件夹
- 【基础原理】HTTP协议(二)
- kindeditor编辑器 php获取内容
- 最简易清晰明了的hibernate双向多对一注解配置
- YARN调度相关整理
- 自定义Topbar
- Codeforces Round #397 Problem E. Tree Folding 解题报告
- 搭建Apache服务器(配置)