Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1380275
  • 博文数量: 860
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-20 19:57
个人简介

对技术执着

文章分类

全部博文(860)

文章存档

2019年(16)

2018年(12)

2015年(732)

2013年(85)

2012年(15)

我的朋友

分类: LINUX

2015-03-14 15:37:52

原文地址:裸奔之IIC 作者:草根老师

一、IIC总线介绍

IIC(Inter-Integrated Circuit,又称IIC)总线是一种由PHILIPS公司开发的串行总线,用于连接微控制器及其外围设备,它具有如下特点。

(1)只有两条总线线路:一条串行数据线(SDA),一条串行时钟线(SCL)
(2)每个连接到总线的器件都可以使用软件根据它的唯一的地址来识别
(3)传输数据的设备间是简单的主/从关系
(4)主机可以用作主机发送器或主机接收器
(5)它是一个真正的多主机总线,两个或多个主机同时发起数据传输时,可以通过冲突检测和仲裁来防止数据被破坏
(6)串行的8位双向数据传输,位速率在标准模式下可达100kbit/s,在快速模式下可达400kbit/s,在高速模式下可达3.4Mbit/s

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

二、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.按字节写操作
 
 

  1. //写EEPROM
  2. int write_EEPROM(int memaddr,int devaddr,int data)
  3. {
  4.     //发送起始信号
  5.     START_IIC(devaddr,MASTER_SEND_MODE,WRITE);    
  6.     
  7.     while(!GET_ACK);//wait ACK
  8.     GET_ACK = 0;
  9.     
  10.     //发送存储地址
  11.     SEND_IIC(memaddr);
  12.     //重新生效
  13.     RESUME_IIC(ACK);

  14.     while(!GET_ACK);//wait ACK
  15.     GET_ACK = 0;
  16.     
  17.     //发送数据
  18.     SEND_IIC(data);
  19.     //重启IIC
  20.     RESUME_IIC(ACK);

  21.     while(!GET_ACK);//wait ACK
  22.     GET_ACK = 0;
  23.     
  24.     //发送停止信号
  25.     STOP_IIC(MASTER_SEND_MODE);
  26.     //重启IIC
  27.     RESUME_IIC(ACK);

  28.     delay(100);

  29.     return 0;
  30. }

C.按字节读操作
 
 

  1. //读EEPROM
  2. int read_EEPROM(int memaddr,int devaddr,char *addr)
  3. {
  4.     //发送起始信号 ,
  5.     START_IIC(devaddr,MASTER_SEND_MODE,WRITE);
  6.     
  7.     while(!GET_ACK);//wait ACK
  8.     GET_ACK = 0;
  9.     
  10.     //发送存储地址
  11.     SEND_IIC(memaddr);    
  12.     RESUME_IIC(ACK);
  13.     
  14.     while(!GET_ACK);//wait ACK
  15.     GET_ACK = 0;
  16.     
  17.     //发送起始信号,
  18.     START_IIC(devaddr,MASTER_RECV_MODE,READ);
  19.     RESUME_IIC(ACK);

  20.     while(!GET_ACK);//wait ACK
  21.     GET_ACK = 0;
  22.     
  23.     RESUME_IIC(NACK);    
  24.     //接收数据
  25.     RECV_IIC(addr);

  26.     //发送停止信号
  27.     STOP_IIC(MASTER_RECV_MODE);
  28.     RESUME_IIC(ACK);

  29.     delay(100);

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

最后附上整个实验的代码:
 IIC.zip   
阅读(449) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~