I2C总线相关_4
2017-03-28 20:33
253 查看
I2C会话分为两种
一种是读会话,一种是写会话
这两种会话都有固定的格式,按照数据手册上的时序写就行了
下面提供的是标准的I2C时序
特别注意下面的DELAY(x) 宏,你可以定义为你需要的时间.
时间可以从芯片手册中得知.
注意:I2C可以由内核中I2C框架实现,也可以用GPIO模拟I2C来实现.
两者的切换需要配置复用寄存器
//这是标准i2c的流程
一种是读会话,一种是写会话
这两种会话都有固定的格式,按照数据手册上的时序写就行了
下面提供的是标准的I2C时序
特别注意下面的DELAY(x) 宏,你可以定义为你需要的时间.
时间可以从芯片手册中得知.
注意:I2C可以由内核中I2C框架实现,也可以用GPIO模拟I2C来实现.
两者的切换需要配置复用寄存器
//写会话 EXPORT_SYMBOL(gpio_i2c_write); void gpio_i2c_write(unsigned char devaddress, unsigned char address, unsigned char data) { i2c_start_bit(); i2c_send_byte(devaddress); i2c_receive_ack(); i2c_send_byte(address); i2c_receive_ack(); i2c_send_byte(data); i2c_receive_ack(); i2c_stop_bit(); }
//这是标准i2c的流程
/* * sends a start bit via I2C rountine. * */ static void i2c_start_bit(void) { DELAY(1); i2c_set(SDA | SCL); DELAY(1); i2c_clr(SDA); DELAY(1); } //一般起始位都是在SDA与SCL同时高的时候,拉低SDA,这就开始了.
/* * sends a character over I2C rountine. * * @param c: character to send * */ static void i2c_send_byte(unsigned char c) { int i; local_irq_disable(); for (i=0; i<8; i++) { DELAY(1); i2c_clr(SCL); DELAY(1); if (c & (1<<(7-i))) i2c_set(SDA); else i2c_clr(SDA); DELAY(1); i2c_set(SCL); DELAY(1); i2c_clr(SCL); } DELAY(1); local_irq_enable(); } //一般发送字节,要不是发送的地址,就是发送的数据,起始都是一样的,都是将字节的字节发送,从最高位到最低位.
/* receives an acknowledge from I2C rountine. * * @return value: 0--Ack received; 1--Nack received * */ static int i2c_receive_ack(void) { int nack; unsigned char regvalue; DELAY(1); regvalue = HW_REG(GPIO_0_DIR); regvalue &= (~SDA); HW_REG(GPIO_0_DIR) = regvalue; DELAY(1); i2c_clr(SCL); DELAY(1); i2c_set(SCL); DELAY(1); nack = i2c_data_read(); DELAY(1); i2c_clr(SCL); DELAY(1); // i2c_set(SDA); // DELAY(1); if (nack == 0) return 1; return 0; } //在往总线上发送一个字节之后,从机设备会发回一个ack,也就是回应,我们需要捕获这个回应.然后鉴别是否正确
/* * sends a stop bit via I2C rountine. * */ static void i2c_stop_bit(void) { /* clock the ack */ DELAY(1); i2c_set(SCL); DELAY(1); i2c_clr(SCL); /* actual stop bit */ DELAY(1); i2c_clr(SDA); DELAY(1); i2c_set(SCL); DELAY(1); i2c_set(SDA); DELAY(1); } //停止位,一般是在SDA和SCL同时为高的时候拉低SDA,然后代表依次会话结束.
//读会话 EXPORT_SYMBOL(gpio_i2c_read); unsigned char gpio_i2c_read(unsigned char devaddress, unsigned char address) { int rxdata; i2c_start_bit(); i2c_send_byte(devaddress); i2c_receive_ack(); i2c_send_byte(address); i2c_receive_ack(); i2c_start_bit(); i2c_send_byte((unsigned char)(devaddress) | 1); i2c_receive_ack(); rxdata = i2c_receive_byte(); i2c_send_ack();//注意,这里是读ack i2c_stop_bit(); return rxdata; } //读的周期一般比较长.
相关文章推荐
- I2C总线相关_2
- I2C总线的相关程序
- I2C总线相关_5
- I2C总线相关_6
- BeagleBone Black I2C总线相关操作
- I2C总线相关_3
- I2C总线相关_1
- i2c适配器驱动源码分析(i2c总线驱动)
- Linux I2C核心、总线与设备驱动
- 第十五章 Linux I2C核心、总线与设备驱动
- I2C总线的仲裁过程
- I2C总线的同步和仲裁
- 详解S3C2440之I2C总线协议
- I2C总线原理及应用实例
- Linux I2C子系统分析-I2C总线驱动
- i2c 相关知识总结
- 总线错误和段错误相关概念
- I2C总线SCL信号无法正常拉高的问题
- I2C总线
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)