NormalSpeed:100Kbps
Fast Speed: 400Kbps
High Speed: 3.5Mbps
1、 空闲状态
I2C总线空闲时,SDA和SCL两条信号线同时处于高电平。
因此,通常I2C都会有外接上拉电阻,在I2C空闲时,SCL和SDA处于高电平状态。
这里空闲不是指睡眠状态,在睡眠状态SCL和SDA是低电平的。
2、 启动信号
SCL保持高电平,SDA从高到低变化;
3、 停止信号
SCL保持高电平,SDA从低到高变化;
4、 数据传送
读取SDA电平时,SCL保持高电平
SDA电平变化时,SCL保持低电平
5、 应答信号
应答位,即ACK,I2C总线8位字节传送完成后,有接收器发送一个ACK信号。
即SCL在第9位时,SDA被接收器拉为低电平,发送器读取SDA为低电平时,即应答有效。
每传送一字节都需要应答信号。
1、 地址格式
I2C采用7位地址寻址,加上读写标志位。
所以通常slave address = slave chip address << 1;
2、 传送过程
启动信号Slave Address + R/W --> ACK --> Data --> ACK --> Data --> ACK -->*******--> 停止信号
代码:
//设置你自己的要配置的GPIO #define SCL GPIO_SCL #define SDA GPIO_SDA #define DELAY 5 /* GPIO 初始化配置 */ /* I2C的gpio 如果外部有上拉电阻的话,就配置成None Pull,如果没有上拉电阻,就配置成Pull-UP */ void gpio_i2c_init(void) { s3c_gpio_cfgpin(SCL, S3C_GPIO_INPUT); s3c_gpio_cfgpin(SDA, S3C_GPIO_INPUT); s3c_gpio_setpull(SCL, S3C_GPIO_PULL_UP); s3c_gpio_setpull(SDA, S3C_GPIO_PULL_UP); s5p_gpio_set_drvstr(SCL, S5P_GPIO_DRVSTR_LV4); s5p_gpio_set_drvstr(SDA, S5P_GPIO_DRVSTR_LV4); } /* 启动信号 */ void i2c_start(void) { gpio_direction_output(SDA, 1); gpio_direction_output(SCL, 1); udelay(DELAY); gpio_set_value(SDA, 0); udelay(DELAY); gpio_set_value(SCL, 0); udelay(DELAY); } /* 停止信号 */ void i2c_stop(void) { gpio_set_value(SCL, 0); gpio_set_value(SDA, 0); udelay(DELAY); gpio_set_value(SCL, 1); udelay(DELAY); gpio_set_value(SDA, 1); udelay(DELAY); } /* 发送ACK */ void i2c_send_ack(u8 ack) { if(ack) gpio_direction_output(SDA, 1); else gpio_direction_output(SDA, 0); udelay(DELAY); gpio_set_value(SCL, 1); udelay(DELAY); gpio_set_value(SCL, 0); udelay(DELAY); } /* 接收ACK */ u8 i2c_receive_ack(void) { u8 rc = 0; gpio_direction_input(SDA); gpio_set_value(SCL, 1); udelay(DELAY); if(gpio_get_value(SDA)) { rc = 1; } gpio_set_value(SCL, 0); gpio_direction_output(SDA, 1); return rc; } /* 发送字节 */ u8 i2c_send_byte(u8 send_byte) { u8 rc = 0; u8 out_mask = 0x80; u8 value; u8 count = 8; while(count > 0) { value = ((send_byte & out_mask) ? 1 : 0); if (value == 1) { gpio_set_value(SDA, 1); } else { gpio_set_value(SDA, 0); } udelay(DELAY); gpio_set_value(SCL, 1); udelay(DELAY); gpio_set_value(SCL, 0); udelay(DELAY); out_mask >>= 1; count--; } gpio_set_value(SDA, 1); rc = i2c_receive_ack(); return rc; } /* 发送字节 */ void i2c_read_byte(u8 *buffer, u8 ack) { u8 count = 0x08; u8 data = 0x00; u8 temp = 0; gpio_direction_input(SDA); while(count > 0) { gpio_set_value(SCL, 1); udelay(DELAY); temp = gpio_get_value(SDA); data <<= 1; if (temp) data |= 0x01; gpio_set_value(SCL, 0); udelay(DELAY); count--; } i2c_send_ack(ack);//0 = ACK 1 = NACK *buffer = data; } /* 使用方法*/ static int gpio_i2c_read_data(struct i2c_client *client, u16 reg, u8 *values, u16 length) { u8 *reg_u8; u8 rc; int i,j; reg_u8 = (u8 *)® printk("gpio_i2c_read_data:length:%d\n",length); gpio_i2c_init();//初始化GPIO i2c_start();//启动信号 rc = i2c_send_byte((client->addr << 1) | 0x00);//Slave Address 写数据 if(rc) { printk("i2c_send_byte no ack 1\n"); return -1; } for(j = 0; j < 2; j++) { rc = i2c_send_byte(reg_u8[j]);//发送data if(rc) { printk("i2c_send_byte no ack 2\n"); return -1; } } i2c_stop();//停止信号 udelay(200); i2c_start();//启动信号 rc = i2c_send_byte( (client->addr << 1) | 0x01 );//发送从机地址 读命令 if(rc) { printk("i2c_send_byte no ack 3\n"); return -1; } for(i = 0; i < length; i++) { i2c_read_byte(values++, !(length - i -1));//读取数据 } i2c_stop();//停止信号 gpio_i2c_init(); return length; }