linux之I2C裸机驱动解析(转)
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裸机驱动解析(转)的更多相关文章
- linux下i2c的驱动架构分析和应用
i2c在linux下的代码在/driver/i2c下面,总体代码如下所示: i2c-core.c 这个文件实现了I2C核心的功能以及/proc/bus/i2c*接口. i2c-dev.c 实现 ...
- Linux kernel 之 uart 驱动解析
uart 是一种非常之常见的总线,比如DEBUG信息输出,小数据量数据传输,485,以及蓝牙的控制,GPS,很多都是通过uart 进行数据传输并进行控制. 在Linux kernel 内部,uart ...
- I2C裸机驱动程序设计
① I2C(Inter-Integrated Circuit)总线是由飞利浦公司开发的两线式串行总线,用于连接微控制器及其外围设备 ② I2C总线有两根双向信号线 (1)SDA:Serial Data ...
- [国嵌攻略][153][I2C裸机驱动设计]
eeprom简介 eeprom电可擦除可编程只读存储器,是一种类似于flash的固态存储器,但是与flash相比又存在一些区别: 1.eeprom可以按位擦写,而flash只能大片擦除. 2.eepr ...
- Linux I2C设备驱动编写(一)
在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I2C driver 某个I2C设备的设备驱动,可以以driver理解. I2C client 某个I2C ...
- 【转】Linux I2C设备驱动编写(一)
原文网址:http://www.cnblogs.com/biglucky/p/4059576.html 在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I ...
- 【驱动】linux下I2C驱动架构全面分析
I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...
- TQ2440学习笔记——Linux上I2C驱动的两种实现方法(1)
作者:彭东林 邮箱:pengdonglin137@163.com 内核版本:Linux-3.14 u-boot版本:U-Boot 2015.04 硬件:TQ2440 (NorFlash:2M Na ...
- linux下I2C驱动架构全面分析【转】
本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...
随机推荐
- JQuery基础教程:选择元素(下)
DOM遍历方法 利用前面介绍的jQuery选择符取得一组元素,就像是我们在DOM树中纵横遍历再经过筛选得到的结果一样.如果只有这一种取得元素的方式,那我们选择的余地从某个角度讲也是很有限的.很多情 ...
- 如果出现isapi和CGI限制的时候
将isapi和CGI中对应的不允许改为允许即可
- 《Head First 设计模式》ch.1 策略(Strategy)模式
策略模式 定义了算法族,分别封装起来,让它们可以互相替换,让算法的变化独立于使用算法的客户. 模式名词的意义 威力强大,交流的不止是模式名称,而是一整套模式背后所象征的质量.特性.约束 用更少的词汇做 ...
- Bootstrap 3 How-To #1 下载与配置
Bootstrap 3 发布了,通过简单的几步,我们就可以使用 Bootstrap 的样式表,图标,以及 javascript 来配置一个简单的站点. 准备 Bootstrap 不仅仅是一个代码集,还 ...
- 长期内部推荐SAP职位,包括Java ABAP 咨询顾问,Developer,架构师等。
长期内部推荐SAP职位,包括Java ABAP 咨询顾问,Developer,架构师等. 有需要请发简历到邮箱 LoB Position LocationAcquisitions Hybris ...
- flex经验记录(转载)
最近一直忙于项目,很好抽出时间学习,刚忙里偷闲浏览博客看到一位博友总结的一些flex的经验,感觉不错就转载过来,一来扩散一下,二来保存下来,以后忘记的时候可以回来学习下. 原博文地址:http://b ...
- Eclipse 工作目录被破坏,导致Eclipse 打不开
由于之前一直使用的的是 visual studio 的开发工具,对 java 的 Eclipse 工具比较陌生,在使用 eclipse 的过程中误删了工作目录的部分文件,导致在在下次启动 eclips ...
- Sco Openserver下 配置SSH服务(图解)
Sco Openserver下 配置SSH服务 好久没玩儿Sco Unix系统了,春节过后为邮政系统的一个朋友调试系统( 装了个远程服务) ,这两天将安装过程回忆了一下,总结出来给大家分享. 本试验需 ...
- 在C++中调用DLL中的函数 (3)
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
- css 字间距离_css 字体字符间距设置
介绍下css 字间距,使用css来控制字与字之间距离,也叫css字间距方法. 使用到的css样式属性单词text-indent抬头距离,letter-spacing字与字间距. Css字间距.div ...