1、I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备(特别是外部存储器件)。
2、I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。
3、I2C总线在传送数据过程中共有三种特殊类型信号, 它们分别是:开始信号、结束信号和应答信号。
4、I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。I2C总线的另一个优点是,它支持多主机,其中任何能够进行发送和接收的设备都可以成为主机。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主机。
5、 I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。各种I2C均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址。
下面是我的电路板单片机引脚接线情况:
第16、17号引脚接的就是SDA、SCL.
下面是SCL和SDA接的EEPROM,通过单片机的两个引脚连接一个外围存储器.
前面说IIC有三种信号 先看开始信号:
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号; 终止信号:
SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
若用代码表示开始信号:
// 只有在SCL为0时才能将SDA改变,SCL为高x相当于告诉别人SDA不会被改变了 // 当在SCL为高时改变SDA状态,只会被识别成开始或终止状态 Void StartIIC() {
// 首先我们需要将SDA和SCL置成高,变成上图最开始状态 SCL = 0; // 延时 Delay();
// 将SDA置高, SDA = 1; Delay();
// 再将SCL置高,此时SDA和SCL都为高电平 SCL = 1; Delay();
// 一切就绪,就等着SDA在SCL为高时变低,表示开始了 SDA = 0; Delay();
// 将SCL = 0 SCL = 0; Delay(); }
再看看终止信号: Void StopIIC() {
// 终止就是要先将SCL置高,SDA置低,然后在此基础上将SDA置高 // 先将SCL置0,便于将SDA改变 SCL = 0; Delay(); SDA = 0; Delay(); SCL = 1; Delay();
// 此时SCL = 1,SDA = 0;
// 将SDA = 1,表示终止信号 SDA = 1; Delay(); }
之所以将SCL好SDA在0和1,就像两个相隔很远的人通过两个手电的光信号交流一样,高电平表示打开手电,低电平表示不开手电没有光,每一秒记录一个状态。一切根据上面的图来写程序。
IIC通信的读和写:
1,I2C与UART不同的地方首先在于先传高位,后传送低位。
2,主机写数据时,每发送一个字节,接收机需要回复一个应答位“0”,通过应答位来判断从机是否接收成功。
3,主机读数据时,接收一个字节结束后,主机也需要发送一应答位“0”,但是当接收最后一个
字节结束后,则需发送一个非应答位“1”,发完了1后,再发一个停止信号,最终结束通信。 写:
首先I2C起始信号,然后发送首字节,即器件(EEPROM)地址。并且在读写方向位上选择“写操作”方向。(0xa0)
第二个字节,发送数据的存储地址,就是要读取的数据所存储在EEPROM中的位置。 第三个字节,发送要存储的数据第一个字节,第二个字节?? 在写数据的过程中,都要等待EEPROM返回一个“应答位”。
先大概看一下写数据的过程:
Void WriteIIC(unsigned char address,unsigned char d) {
// 开始信号 StartIIC();
// 写器件地址,1010 xxxy(x表示地址,y表示操作方式,0表示写,1表示读) SendData(0xa0);
// 写操作数据的地址 SendData(address); // 写入数据 SendData(d); // 终止信号 StopIIC(); }
其中有个SendData(unsigned char d)函数,传入数据d,然后通过改变SCL和SDA的高低来发送数据。
Void SendData(unsigned char d) { // 向EEPROM写数据
// 一位一位的发送 unsigned char temp = 0x80,i; for (i = 0;i < 8;i ++) { SCL = 0; Delay(); if ((c & temp) != 0) { // 真表示测试位是1 SDA = 1; } else { // 假表示测试位是0 SDA = 0; } temp >>= 1; // 将scl置高,让EEPROM有机会读取SDA上的信息 Delay(); SCL = 1;
Delay(); } // 最后再接收一个应答位 SCL = 0; Delay(); SDA = 1; Delay(); SCL = 1; Delay(); // 此时SDA已经接收到一个应答位,暂不处理 //if (SDA != 0) //{ // 没有接收到应答位,返回错误 //return 0; //} SCL = 0; return 1; }
IIC通信的读数据:
首先I2C起始信号,然后发送首字节,即器件(EEPROM)地址。并且在读写方向位上选择“写操作”方向。
第二个字节,发送数据的存储地址,就是要读取的数据所存储在EEPROM中的位置。 第三个字节,重新发送I2C起始信号和器件地址,并且在方向位上选择“读操作”方向。 在前三个字节操作过程,都要等待器件给与回应一个“应答位0”
第四个字节,接收从器件发回的首字节后,单片机要主动返回一个“(非)应答位0”??
Unsigned char ReadIIC(unsigned char address) {
Unsigned char d = 0; // 起始信号 StartIIC(); // 写设备地址 SendData(0xa0); // 写数据地址 SendData(address); // 重新发送起始信号 StartIIC();
// 写设备地址和操作方式为读 SendData(0xa1); // 得到读取的数据 d = ReadData(); // 终止信号 StopIIC();
Return d; }
unsigned char ReadData() {