s3c2440的IIC控制
在tq2440和mini2440上都连接着EEPROM 它们作用也不过測试I2C总线能否用。
当中在mini2440上EEPROM型号是 AT24C08,在tq2440上这个型号是 AT24C02A。
它们之间容量不同。地址线也不一样。
S3C2440A RISC 微处理器能够支持一个多主控 IIC 总线串行接口。一条串行数据线(SDA)和一条专用时钟线(SCL) 连接到 IIC 总线的总线主控和外设之间。SDA 和 SCL 线都为双向的。都连接到GPE14(SCL) GPE15(SDA)。
为了控制多主控 IIC 总线操作,必须写入值到下面寄存器中:
– 多主控 IIC 总线控制寄存器,IICCON
– 多主控 IIC 总线控制/状态寄存器,IICSTAT
– 多主控 IIC 总线 Tx/Rx 数据移位寄存器,IICDS
– 多主控 IIC 总线地址寄存器,IICADD
因为我们仅仅把s3c2440当做主设备来用,而且系统的IIC总线上仅仅有这么一个主设备,因此用来设置从设备地址的地址寄存器IICADD无需配置。
S3C2440A 的 IIC 总线接口有 4 种工作模式:
– 主机发送模式
– 主机接收模式
– 从机发送模式
– 从机接收模式
起始和停止条件
当 IIC 总线接口不活动时,其通常在从机模式。
换句话说,该接口在从 SDA 线上检測到起始条件之前应该处于从机模式(当 SCL 时钟信号为高时的一个高到低 SDA 的变化可
以启动一个起始条件)。当接口状态被改为主机模式时,能够起始发送数据到 SDA 上而且产生 SCL 信号。
起始条件能够传输 1 字节串行数据到 SDA 线上,而停止条件能够结束
数据的传输。
停止条件是在当 SCL 为高时的 SDA 线低到高的变化。起始和停止条件总由主机产生。当产生了一个起始条件时 IIC 总线变为忙。停止条件将使得 IIC 总线空暇。
当主机发起一个起始条件时,其应该送出一个从机地址来通知从设备。
地址字段的 1 字节由 7 位地址和 1 位传输方向标志(表现为读或写)组成。
假设位[8]为 0,其表示一个写操
作(发送操作);假设位[8]为 1,其表示一个数据读取的请求(接收操作)。
主机将通过发送一个停止条件来完毕传输操作。假设主机希望持续发送数据到总线上,其应该在同一个从地址产生再一个起始条件。这样就能够运行各种格式的读写操作。
注意到在 起始 和 停止 条件之间还有若干个SCL时钟。 用来发送数据。
传输数据格式
放置到 SDA 线上的每一个字节应该以 8 位为长度。
每次传输字节能够无限制的发送。起始条件随后的第一个字节应该包括地址字段。当 IIC 总线工作在主机模式时能够由主机
发送该地址字段。
每一个字节都应该尾随一个应答(ACK)位。
总是最先发送串行数据和地址的 MSB。
上图勘误 这里图例应该反过来 --- 灰色框表示从从机到主机,看来翻译文档的人还不够细心呢。
上面提到了4中工作模式,在这里我们仅仅把s3c2440当做IIC总线的主设备来使用。因此仅仅介绍前两种操作模式。
首先看下主设备发送流程图:
首先配置IIC模式,然后把从设备地址写入 接收发送数据移位寄存器IICDS 中。再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号。如
果想要继续发送数据。那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后。再次等待应答信号。假设不想再发送数据了,那么
把0x90写入寄存器IICSTAT中,清除中断标志并等待停止条件后。即完毕了一次主设备的发送。
代码例如以下:
//AT24C02A页写,当sizeofdate为1时。是字节写
//输入參数依次为设备内存地址、IIC数据缓存数组和要写入的数据个数
void __attribute__((optimize("O0"))) wr24c02a(UINT8 wordAddr,UINT8 *buffer,UINT32 sizeofdate )
{
int i;
i2cflag =1; //应答标志 rIICDS = devAddr;
rIICSTAT = 0xf0; //主设备发送模式
rIICCON &= ~0x10; //清中断标志 while(i2cflag == 1) //等待从设备应答,
OSTimeDly(2); //一旦进入IIC中断,就可以跳出该死循环 i2cflag = 1; rIICDS = wordAddr; //写入从设备内存地址
rIICCON &= ~0x10; while(i2cflag)
OSTimeDly(2); //连续写入数据
for(i=0;i<sizeofdate;i++)
{
i2cflag = 1;
rIICDS = *(buffer+i);
rIICCON &= ~0x10;
while(i2cflag)
OSTimeDly(2);
} rIICSTAT = 0xd0; //发出stop命令,结束该次通讯
rIICCON = 0xe0; //为下次IIC通讯做准备 OSTimeDly(100);
}
上面有2点地方须要说明。1点是刚開始的初始化 rIICCON 一定要在 rIICSTAT 后面赋值。
第2点是因为这是在多任务环境下执行的,while后面跟的OSTimeDly有延迟,也就是说假设OSTimeDly(2)延迟10ms,而在1ms的时候中断发生了。这里
仍然要延迟10ms才干继续运行,能够考虑用信号量替代。这样一旦发生中断,从中断出来之后就会马上继续运行。
然后就是主设备接收流程图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWHNjS2VybmVs/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
首先配置 IIC 模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xB0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号。假设想要接收数据,那么在应答信号后。读取寄存器IICDS,清除中断标志;假设不想接收数据了,那么就向寄存器IICSTAT写入0x90。清除中断标志并等待停止条件后,即完毕了一次主设备的接收。
//AT24C02A的序列读,当sizeofdate为1时,是随机读
//输入參数依次为设备内存地址、IIC数据缓存数组和要读取的数据个数
void rd24c02a(UINT8 wordAddr,UINT8 *buffer,UINT32 sizeofdate )
{
int i;
unsigned char temp; i2cflag =1;
rIICDS = devAddr; // rIICCON &= ~0x10; //清中断标志
rIICSTAT = 0xf0; //主设备发送模式 while(i2cflag)
OSTimeDly(2); i2cflag = 1; rIICDS = wordAddr;
rIICCON &= ~0x10;
while(i2cflag)
OSTimeDly(2); i2cflag = 1;
rIICDS = devAddr; //
rIICCON &= ~0x10;
rIICSTAT = 0xb0; //主设备接收模式
while (i2cflag)
OSTimeDly(2); i2cflag = 1;
temp = rIICDS; //读取从设备地址
rIICCON &= ~0x10;
while(i2cflag)
OSTimeDly(2); //连续读
for(i=0;i<sizeofdate;i++)
{
i2cflag = 1;
if(i==sizeofdate-1) //假设是最后一个数据
rIICCON &= ~0x80; //不再响应
*(buffer+i) = rIICDS;
rIICCON &= ~0x10;
while(i2cflag)
OSTimeDly(2);
} rIICSTAT = 0x90; //结束该次通讯
rIICCON = 0xe0; // OSTimeDly(100);
}
s3c2440的 IIC 时钟源为PCLK。当系统的 PCLK 为50MHz。而从设备最高须要100kHz时,须要配置IICCON寄存器 例如以下图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWHNjS2VybmVs/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
系统初始化时候配置iic寄存器例如以下:
void init_i2c(void)
{
rGPEUP |= 0xc000; //Pull-up disable
rGPECON |= 0xa0000000; //GPE15:IICSDA , GPE14:IICSCL rINTMSK &= ~(1<<27); /// enable i2c
rIICCON = 0xe0; //设置IIC时钟频率,使能应答信号,并开启中断
rIICSTAT = 0x10;
pIRQ_IIC = (UINT32)i2c_isr;
}
在 i2c_isr 里面也不过把 i2cflag 赋值为0:
void i2c_isr(void)
{
i2cflag = 0;
}
详细的代码能够从我的github上clone。
參考:
博文 http://blog.csdn.net/zhaocj/article/details/5477152
s3c2440文档
atmel_at24c02a Datasheet
s3c2440的IIC控制的更多相关文章
- S3C2440 I2C总线控制
概述:话不多说,直接上图 多主机IIC总线控制(IICCON): IIC控制总线状态(IICSTAT): IIC总线地址(IICADD): IIC发送,接收总线寄存器(IICDS) IIC总线控制寄存 ...
- S3C2440硬件IIC详解
S3C2440A RISC微处理器可以支持一个多主控IIC 总线串行接口.一条专用串行数据线(SDA)和一条专用串行时钟线(SCL)传递连接到IIC总线的总线主控和外设之间的信息.SDA和SCL线都为 ...
- S3C2440之IIC裸机驱动
花了两天的时间终于把这个搞定了,其实I2C的原理还是比较简单的,只是几个细节性的东西还是需要特别的注意,主要是需要注意一下几点: 1.rIICCON &= ~0x10; 清中断必须要在rIIC ...
- S3C2440触摸屏控制总结
触摸屏控制原理,其实与ADC读取一个滑动变阻器中间触点电压的原理一样.只不过,读取触摸屏的X.Y方向上的电压需要两次,而且需要设置其工作模式以实现一个ADC读取两个通道的电压. S3C2440的ADC ...
- IIC驱动分析
IIC设备是一种通过IIC总线连接的设备,由于其简单性,被广泛引用于电子系统中.在现代电子系统中,有很多的IIC设备需要进行相互之间通信 IIC总线是由PHILIPS公司开发的两线式串行总线,用于连接 ...
- IIC设备驱动程序
IIC设备是一种通过IIC总线连接的设备,由于其简单性,被广泛引用于电子系统中.在现代电子系统中,有很多的IIC设备需要进行相互之间通信 IIC总线是由PHILIPS公司开发的两线式串行总线,用于连接 ...
- 【DSP开发】【Linux开发】IIC设备驱动程序
IIC设备是一种通过IIC总线连接的设备,由于其简单性,被广泛引用于电子系统中.在现代电子系统中,有很多的IIC设备需要进行相互之间通信 IIC总线是由PHILIPS公司开发的两线式串行总线,用于连接 ...
- IIC 概述之24c系列存储器内存分析
IIC 型号 容量 器件/业面寻址字节 可寻址位 模块 24C01 128B (1010)(A2)(A1)(A0)(0或 ...
- 基于mini2440的IIC读写(裸机)
mini2440开发板提供的测试代码过于复杂,让人很难理解,而且有些错误,如GPE14-15不能设置上拉电阻,可是代码里却设置了,虽然无关紧要.为了方便学习,我在闲暇之时我研究了一下.IIC的原理是比 ...
随机推荐
- MySQL官方文档
http://dev.mysql.com/doc/refman/5.7/en/index.html 没有比这更好的MySQL文档了,省的去买书了
- 用 C 语言编写一个简单的垃圾回收器
人们似乎觉得编写垃圾回收机制是非常难的,是一种仅仅有少数智者和Hans Boehm(et al)才干理解的高深魔法.我觉得编写垃圾回收最难的地方就是内存分配,这和阅读K&R所写的malloc例 ...
- UVA 294 - Divisors 因子个数
Mathematicians love all sorts of odd properties of numbers. For instance, they consider 945 to be an ...
- wifi破解不是真黑客不靠谱?
Wifi破解神器骗局:摆地摊+网络兜售 近日,"万能wifipassword破解器"风靡全国地摊.各地小贩開始兜售这样的蹭网卡.声称可破解各种wifipassword,当场測试也是 ...
- webview同步cookies
目前很多android app都内置了可以显示web页面的界面,会发现这个界面一般都是由一个叫做WebView的组件渲染出来的,学习该组件可以为你的app开发提升扩展性. 先说下WebView的一些优 ...
- BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher
BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...
- 如何用写js弹出层 ----2017-03-29
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- .NET序列化工具Jil、Json.NET和Protobuf的简单测评
前一段时间逛园子的时候发现有人比较了Jil.Json.NET和Protobuf的性能,一时好奇,也做了个测试,这里记录下来,以供查阅. 前期准备 依赖类库的话,可以通过Nuget在公共组件库总下载,这 ...
- roscore不能启动
通过VNC 在VNC窗口上出入 roscore 得到下面错误信息 ----------------------------------------------------------- proces ...
- 清北集训Day1T3 LYK loves jumping(期望DP)
题目描述 LYK在玩一个魔法游戏,叫做跳跃魔法. 有n个点,每个点有两个属性hi和ti,表示初始高度,和下降高度.也就是说,它初始时高度为hi,一旦LYK踩在这个点上,由于重力的影响,这个点的高度会下 ...