I2C通信原理及程序详细讲解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

I2C 通信:

起始条件:SCL为高电平,SDA电平从高变低,这一变化即完成了通信的起始条件。

起始条件和数据通信间,通常会有延时要求具体的指标见设备说明。

数据传输阶段:一字节需要9个时钟周期;且每一位需要一个时钟周期;如上图所示,ADDRESS为目标设备的地址,R/ w为通信的的方向位;"1"时表示读,即后续的数据由目标设备发出,主机进行接收;"0"时表示写,即后续的数据由主机发出目标设备进行接收。

当ACK信号为"0"时,说明接收成功;为"1"时,说明接收失败。

每个字节的传输都是由高位(MSB)到低位(LSB)依次进行传输。

在数据通信过程中,总是由数据接收方发出ACK信号。

终止阶段:当主机完成数据通信,并终止本次传输时会发出终止信号。当SCL 是高电平时,SDA电平由低变高,这个变化意味着传输终止。注:每个时钟周期的高电平期间,SDA的数据状态达到稳定。

下面给出了模拟I2C总线进行读写的伪代码,用以说明如何使用GPIO 实现I2C通信:

int i2c_start() /* I2C起始条件*/

{

//初始化GPIO口

set_gpio_direction(SDA, OUTP); //设置SDA方向为输出

set_gpio_direction (SCL, OUTP); //设置SCL方向为输出

set_gpio_value(SDA, 1); //设置SDA为高电平

set_gpio_value(SCL, 1); //设置SCL为高电平

delay(); //延时

//起始条件

set_gpio_value(SDA, 0); //SCL为高电平时,SDA由高变低delay(); //适当延时

}

void i2c_stop() /* I2C终止条件*/

{

set_gpio_value(SCL, 1);

set_gpio_direction(SDA, OUTP);

set_gpio_value(SDA, 0);

delay();

set_gpio_value(SDA, 1); //SCL高电平时,SDA由低变高

}

/* I2C读取ACK信号(写数据时使用)返回值:0表示ACK信号有效;非0表示ACK信号无效*/

unsigned char i2c_read_ack()

{

unsigned char r;

set_gpio_direction(SDA, INP); //设置SDA方向为输入

set_gpio_value(SCL,0); // SCL变低

r = get_gpio_value(SDA); //读取ACK信号

delay();

set_gpio_value(SCL,1); // SCL变高

delay();

return r;

}

/* I2C发出ACK信号(读数据时使用) */

int i2c_send_ack()

{

set_gpio_direction(SDA, OUTP); //设置SDA方向为输出

set_gpio_value(SCL,0); // SCL变低

set_gpio_value(SDA, 0); //发出ACK信号

delay();

set_gpio_value(SCL,1); // SCL变高

delay();

}

void i2c_write_byte(unsigned char b) /* I2C字节写*/

{

int i;

set_gpio_direction(SDA, OUTP); //设置SDA方向为输出

for (i=7; i>=0; i--)

{

set_gpio_value(SCL, 0); // SCL变低

delay();

set_gpio_value(SDA, b & (1<

delay();

}

i2c_read_ack(); //检查目标设备的ACK信号}

/* I2C字节读*/

unsigned char i2c_read_byte()

{

int i;

unsigned char r = 0;

set_gpio_direction(SDA, INP); //设置SDA方向为输入

for (i=7; i>=0; i--)

{

set_gpio_value(SCL, 0); // SCL变低

delay();

r = (r <<1) | get_gpio_value(SDA); //高位到低位依次数据读取set_gpio_value(SCL, 1); // SCL变高

delay();

}

i2c_send_ack(); //向目标设备发送ACK信号return r;

}

/* I2C读操作addr:目标设备地址buf:读缓冲区len:读入字节的长度*/

void i2c_read(unsigned char addr, unsigned char* buf, int len)

{

int i;

unsigned char t;

i2c_start(); //起始条件,开始数据通信//发送地址和数据读写方向

t = (addr << 1) | 1; //低位为1,表示读数据

i2c_write_byte(t);

//读入数据

for (i=0; i

buf[i] = i2c_read_byte();

相关文档
最新文档