1      硬件特性

1.1 概述

I2C总线是由Philips公司开发的两线式串行总线,这两根线为时钟线(SCL)和双向数据线(SDA)。由于I2C总线仅需要两根线,因此在电路板上占用的空间更少,带来的问题是带宽较窄。I2C在标准模式下传输速率最高100Kb/s,在快速模式下最高可达400kb/s。属于半双工。

在嵌入式系统中,I2C应用非常广泛,大多数微控制器中集成了I2C总线,一般用于和RTC,EEPROM,智能电池电路,传感器,LCD以及其他类似设备之间的通信。

1.2 I2C总线传输时序

1.3 I2C总线的信号状态

1、  空闲状态:SDA和SCL都是高电平;

2、  开始条件(S):SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据;

3、  结束条件(P):SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据;

4、  数据有效:在SCL的高电平期间,SDA保持稳定,数据有效。SDA的改变只能发生在SCL的低电平期间;

5、  ACK信号:数据传输的过程中,接收器件每接收一个字节数据要产生一个ACK信号,向发送器件发出特定的低电平脉冲,表示已经收到数据。

1.4 从设备地址


I2C总线从设备使用7位地址,最后一个为读写控制位。下图是eeprom的原理图,我们可以计算出它的地址为0x50。

1.5 I2C读写方式

多字节写的时序

多字节读的时序

具体可参考datasheet

附:ok6410裸机I2C代码。

 #define INTPND (*(volatile unsigned long*)0x4a000010)
#define SRCPND (*(volatile unsigned long*)0x4a000000)
#define INTMSK (*(volatile unsigned long*)0x4a000008)
#define GPECON (*(volatile unsigned long*)0x56000040)
#define GPEUP (*(volatile unsigned long*)0x56000048) #define IICCON (*(volatile unsigned char*)0x54000000)
#define IICSTAT (*(volatile unsigned char*)0x54000004)
#define IICDS (*(volatile unsigned char*)0x5400000C) #define SLAVE_WRITE_ADD 0xa0 /* 写入数据时;方向位(第0位)为0 */
#define SLAVE_READ_ADD 0xa1 /* 读取数据时;方向位(第0位)为1 */ void delay(int i)
{
int j = ;
while (i--)
{
for (j=;j<;j++)
{
;
}
}
} void i2c_init()
{
//1.a 初始化中断
INTPND |= (<<);
SRCPND |= (<<);
INTMSK &= ~(<<); IICCON |= (<<); //1.b 设置scl时钟
IICCON &= ~(<<);
IICCON &= ~(0xf<<);
IICCON |= (0x5<<); //2. 设置IICSTAT
IICCON |= (<<); //3.设置引脚功能
GPECON |= (0x2<<)|(0x2<<);
GPEUP |= (0x3<<); //4.允许产生ACK
IICCON |= (<<);
} void write_byte(unsigned char xchar, unsigned char daddr)
{
/* 写入数据时,每发送一个数据收到一个ACK就产生一次中断
* 写入下次发送的数据之后要清除中断 */ //1. 设置处理器为主设备+发送模式
IICSTAT |= (<<); //2. 将从设备的地址写入到IICDS寄存器
IICDS = SLAVE_WRITE_ADD; //清除中断
IICCON &= ~(<<); //3. 写入0xF0写入IICSTAT M/T Start
IICSTAT = 0xF0; //4. 等待ACK的产生
while ((IICCON & (<<)) == )
delay(); //5.1写入字节的地址到IICDS寄存器
IICDS = daddr; //5.2清除中断
IICCON &= ~(<<); //5.3等待ACK的产生
while ((IICCON & (<<)) == )
delay(); //6. 将要传输的字节数据写入IICDS寄存器
IICDS = xchar; //7. 清除中断
IICCON &= ~(<<); //8. 等待ACk的产生
while ((IICCON & (<<)) == )
delay(); //9. 写入0xD0到IICSTAT
IICSTAT = 0xD0; //10. 清除中断
IICCON &= ~(<<); delay();
} void read_data(unsigned char *buf, unsigned char daddr, int length) /* 结合eeprom手册 */
{
/* 每接收一个数据产生一个中断 */ int j =;
unsigned char unusedata; //1. 设置处理器为主设备+发送模式
IICSTAT |= (<<); //2. 将从设备的地址写入到IICDS寄存器
IICDS = SLAVE_WRITE_ADD; //清除中断
IICCON &= ~(<<); //3. 写入0xF0写入IICSTAT M/T-Start
IICSTAT = 0xF0; //4. 等待ACK的产生
while ((IICCON & (<<)) == )
delay(); //5.1写入eeprom内部地址
IICDS = daddr; //5.2清除中断
IICCON &= ~(<<); //5.3等待ACK的产生
while ((IICCON & (<<)) == )
delay(); /**************eeprom代码**************/
/**************************************/
/***************i2c代码****************/ //设置为主设备接收模式
IICSTAT &= ~(<<);
IICSTAT |= (<<); //2.写入从设备地址到IICDS /* 从设备地址成功发送之后产生中断,故要清除中断 */
IICDS = SLAVE_READ_ADD;
//清除中断
IICCON &= ~(<<); //3.写入0xB0到IICSTAT开始接收,每接收道一个数据就产生一个中断
IICSTAT = 0xb0; //等待中断
while ((IICCON & (<<)) == )
delay(); #if 0
/***写入设备内部地址***/
IICDS = daddr;
IICCON &= ~( << );
while((IICCON & ( << )) == )
{
delay();
}
#endif //***丢掉收到的第1个字节 第一个数据无效 丢弃!
unusedata = IICDS;
IICCON &= ~(<<);
while ((IICCON & (<<)) == )
delay(); for(j=;j<length;j++)
{
if(j == (length - ))
{
IICCON &= ~(<<);
} //5.1 从IICDS里取出数据
buf[j]=IICDS; //5.2 清除中断
IICCON &= ~(<<); //4.等待中断
while ((IICCON & (<<)) == )
delay();
} //写入0x90到IICSTAT
IICSTAT = 0x90; // 清除中断
IICCON &= ~(<<);
} void i2c_test()
{
int i=;
unsigned char sbuf[]={};
unsigned char dbuf[]={}; i2c_init(); for(i=;i<;i++)
{
sbuf[i] = i+;
dbuf[i] = ;
} printf("dbuf befor I2C read:\r\n");
for(i =; i<;i++)
{
if(i%==)
printf("\r\n"); /* */ printf("%d\t",dbuf[i]); /*t-空格 */
} for(i=;i<;i++)
write_byte(sbuf[i],i); printf("i2c reading, plese wait!\n\r"); read_data(dbuf,,); printf("dbuf after I2C read:\r\n"); for(i =; i<;i++)
{
if(i%==)
printf("\r\n"); printf("%d\t",dbuf[i]);
}
}

linux之I2C裸机驱动解析(转)的更多相关文章

  1. linux下i2c的驱动架构分析和应用

    i2c在linux下的代码在/driver/i2c下面,总体代码如下所示: i2c-core.c 这个文件实现了I2C核心的功能以及/proc/bus/i2c*接口.    i2c-dev.c  实现 ...

  2. Linux kernel 之 uart 驱动解析

    uart 是一种非常之常见的总线,比如DEBUG信息输出,小数据量数据传输,485,以及蓝牙的控制,GPS,很多都是通过uart 进行数据传输并进行控制. 在Linux kernel 内部,uart ...

  3. I2C裸机驱动程序设计

    ① I2C(Inter-Integrated Circuit)总线是由飞利浦公司开发的两线式串行总线,用于连接微控制器及其外围设备 ② I2C总线有两根双向信号线 (1)SDA:Serial Data ...

  4. [国嵌攻略][153][I2C裸机驱动设计]

    eeprom简介 eeprom电可擦除可编程只读存储器,是一种类似于flash的固态存储器,但是与flash相比又存在一些区别: 1.eeprom可以按位擦写,而flash只能大片擦除. 2.eepr ...

  5. Linux I2C设备驱动编写(一)

    在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I2C driver 某个I2C设备的设备驱动,可以以driver理解. I2C client 某个I2C ...

  6. 【转】Linux I2C设备驱动编写(一)

    原文网址:http://www.cnblogs.com/biglucky/p/4059576.html 在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I ...

  7. 【驱动】linux下I2C驱动架构全面分析

    I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...

  8. TQ2440学习笔记——Linux上I2C驱动的两种实现方法(1)

    作者:彭东林 邮箱:pengdonglin137@163.com 内核版本:Linux-3.14 u-boot版本:U-Boot 2015.04 硬件:TQ2440 (NorFlash:2M   Na ...

  9. linux下I2C驱动架构全面分析【转】

    本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...

随机推荐

  1. 使用kendoui对grid指定行变色

    关键点在于绑定数据源后进行判断,可直接获取当前绑定对象的属性 dataBound: function () { dataView = this.dataSource.view(); ; i < ...

  2. leetcode题目总结(转)

    https://www.douban.com/note/330562764/   http://blog.csdn.net/lanxu_yy/article/details/17848219   ht ...

  3. Flash与IE奇怪的关键字冲突

    我有一个小小的swf文件,用来播放声音,加入到HTML后,在Firefox/chrome下播放正常,唯独IE8提示 消息: 对象不支持此属性或方法 行: 48 字符: 3 代码: 0 URI: ... ...

  4. Openstack-Mitaka Ceilometer 中使用 SNMP 监控真实物理机

    Ceilometer 是 Openstack 的监控管理计费模块,我所用的版本为 Mitaka 版本.在 Ceilometer 中,可以使用 SNMP 监控服务器的实时硬件资源信息. 系统环境为 Ce ...

  5. 【LeetCode】7. Reverse Integer 整型数反转

    题目: Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 思路:不 ...

  6. 请添加 MIME 映射

    HTTP 错误 404.3 - Not Found 由于扩展配置问题而无法提供您请求的页面.如果该页面是脚本,请添加处理程序.如果应下载文件,请添加 MIME 映射. 以管理员运行命令:C:\Wind ...

  7. django中时区设置

    通过django中的models更新数据库的DateTimeField字段,发现有错误,于是更改了: TIME_ZONE = 'Asia/Shanghai' 结果,还是不正确,于是把: USE_TZ ...

  8. Oracle对表解锁的操作

    1.查出被锁的表 SELECT  lpad(' ',decode(l.xidusn ,0,3,0))||l.oracle_username User_name, o.owner,o.object_na ...

  9. 洛谷P2733 家的范围 Home on the Range

    P2733 家的范围 Home on the Range• o 26通过o 61提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论• 暂时没有讨论题目背景 ...

  10. WebLogic集群案例分析

    WebLogic集群案例分析 2012年8月,某证券交易系统(采用Weblogic中间件),由于基金业务火爆,使系统压力太大,后台服务器频繁死机时,这时工程师们紧急调试系统及恢复操作,等完成这些操作花 ...