博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
裸奔之IIC
阅读量:7241 次
发布时间:2019-06-29

本文共 2320 字,大约阅读时间需要 7 分钟。

 

转载:

 

I2C总线协议中文版:

 

一、IIC总线介绍

 
IIC(Inter-Integrated Circuit,又称IIC)总线是一种由PHILIPS公司开发的串行总线,用于连接微控制器及其外围设备,它具有如下特点。
 
(1)只有两条总线线路:一条串行数据线(SDA),一条串行时钟线(SCL)
(2)每个连接到总线的器件都可以使用软件根据它的唯一的地址来识别
(3)传输数据的设备间是简单的主/从关系
(4)主机可以用作主机发送器或主机接收器
(5)它是一个真正的多主机总线,两个或多个主机同时发起数据传输时,可以通过冲突检测和仲裁来防止数据被破坏,同一时间只能有一个主机占用总线
(6)串行的8位双向数据传输,位速率在标准模式下可达100kbit/s,在快速模式下可达400kbit/s,在高速模式下可达3.4Mbit/s
(7)总线长度最长 7.6m 左右
(8)片上滤波器可以增加抗干扰能力,保证数据的完成传输
(9)连接到一条 IIC 总线上的设备数量只受到最大电容 400pF 的限制。 IIC 总线是 7 位的地址, 27 次方是 128。实现应用中由于电容等方面的限制,总线上面连接的 IIC 设备,不会太多
(10)传输时,先传输最高有效位MSB
(11)发送到 SDA 线上的每个字节必须为 8

注意:当多个主机试图去控制总线时,通过仲裁可以使得只有一个主机获得总线控制权,并且它传输的信息不被破坏
 

二、IIC总线的信号类型

 
IIC总线在传送数据过程中共有3种类型信号:开始信号、结束信号和响应信号
 
(1)开始信号(S):SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据
(2)结束信号(P):SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据
 

(3)响应信号(ACK):接收器在接收到8位数据后,在第9个时钟周期,拉低SDA电平

注意:SDA上传输的数据必须在SCL为高电平期间保持稳定,SDA上的数据只能在SCL为低电平期间变化
 

三、IIC总线的数据传输格式

 
发送到SDA线上的每个字节必须是8位的,每次传输可以发送的字节数量不受限制。首先传输的是数据的最高位(MSB)。

启动一个传输时,主机先发送S信号,然后发出8位数据。这8位数据中前7位为从机的地址,第8位表示传输的方向(0表示写操作,1表示读操作)。从机收到后会发出一个ACK信号(低电平).

注意:主机接收器在接收到最后一个字节后,也不会发出ACK信号。于是,从机发送器释放SDA线,以允许主机发出P信号结束传输.
 

四、以EEPROM实例讲解

 

先来看看原理图

这里使用的是AT24C04型号的EEPROM,原理图上标错了,正确的是下面这个

A.先获得EEPROM的作为从设备的地址

可以看出前4位是固定的,后三位从原理图上可以知道都接地了,所以全为0。这样其地址就为0xa0

B.按字节写操作

代码:

//写EEPROMint write_EEPROM(int memaddr,int devaddr,int data){    //发送起始信号     START_IIC(devaddr,MASTER_SEND_MODE,WRITE);        while(!GET_ACK);//wait ACK     GET_ACK = 0;    //发送存储地址    SEND_IIC(memaddr);    //重新生效     RESUME_IIC(ACK);    while(!GET_ACK);//wait ACK     GET_ACK = 0;    //发送数据     SEND_IIC(data);    //重启IIC     RESUME_IIC(ACK);    while(!GET_ACK);//wait ACK     GET_ACK = 0;    //发送停止信号     STOP_IIC(MASTER_SEND_MODE);    //重启IIC     RESUME_IIC(ACK);    delay(100);    return 0;}

C.按字节读操作

 

//读EEPROMint read_EEPROM(int memaddr,int devaddr,char *addr){    //发送起始信号 ,写    START_IIC(devaddr,MASTER_SEND_MODE,WRITE);    while(!GET_ACK);//wait ACK     GET_ACK = 0;    //发送存储地址     SEND_IIC(memaddr);        RESUME_IIC(ACK);    while(!GET_ACK);//wait ACK     GET_ACK = 0;    //发送起始信号,读    START_IIC(devaddr,MASTER_RECV_MODE,READ);    RESUME_IIC(ACK);    while(!GET_ACK);//wait ACK     GET_ACK = 0;    RESUME_IIC(NACK);        //接收数据    RECV_IIC(addr);    //发送停止信号     STOP_IIC(MASTER_RECV_MODE);    RESUME_IIC(ACK);    delay(100);    return 0;}

这里需要注意的是,当中断产生后,需要将IICCON控制器的第4位清0后IIC才能正常工作

最后附上整个实验的代码:

 

 完。

你可能感兴趣的文章
oracle vm的虚拟机windows启动不了的处理方式
查看>>
Hyper-V 2012实时迁移
查看>>
Microsoft Azure Site Recovery (2) 配置虚拟机保护
查看>>
Microsoft Azure Site Recovery (1) 安装VMM服务器代理
查看>>
【转】动态模型及其求解介绍—上
查看>>
学习 ExtJS 4 面板与布局
查看>>
SQL ALTER TABLE 语句
查看>>
使用jquery提交form表单并自定义action
查看>>
Unity3D引用dll打包发布的问题及解决
查看>>
Android开发之Google Map
查看>>
基于内容的图片检索CBIR(Content Based Image Retrieval)简介
查看>>
VS2012编译LibZip库
查看>>
[置顶] 程序员的奋斗史(二十五)——情绪与生活
查看>>
Linux kernel中网络设备的管理
查看>>
反转字符串
查看>>
FusionCharts或其它flash的div图层总是浮在最上层? (转)
查看>>
[Android] Service和IntentService中显示Toast的区别
查看>>
How Tomcat Works(七)
查看>>
烟大 2239: 十进制与八进制的转换(栈和队列)
查看>>
hdu 4681(枚举+dp)
查看>>