[国嵌攻略][153][I2C裸机驱动设计]
eeprom简介
eeprom电可擦除可编程只读存储器,是一种类似于flash的固态存储器,但是与flash相比又存在一些区别:
1.eeprom可以按位擦写,而flash只能大片擦除。
2.eeprom一般容量都不大,一般都在64kb以下。
I2C初始化
在ARM内部有I2C控制器,可以对I2C器件进行访问。所以I2C初始化也就是对I2C控制器初始化。
1.如果需要,写入处理器的I2C从设备地址。
2.设置IICCON寄存器
2.1.允许中断
2.2.设置SCL周期
3.设置IICSTAT允许串行输出
4.设置GPIO为I2C
5.允许产生ACK
I2C写数据
1.设置处理器为主设备加发送模式
2.将从设备的地址写入到IICDS寄存器
3.写入0xF0到IICSATA
4.等到ACK的产生
5.写入字节地址到IICDS寄存器
6.等待ACK产生
7.将要传输的数据写入IICDS寄存器
8.清除中断
9.等待ACK的产生
10.写入0xD0到IICSATA
11.清除中断
I2C读数据
1.设置为主设备发送模式
2.写入从设备地址
3.写入0xF0到IICSTAT
4.等待ACK
5.写入eeprom内部地址
6.等待ACK
7.设置为主设备接收模式
8.写入从设备地址到IICDS
9.写入0xB0到IICSTAT开始接收
10.等待中断
11.1.如果是最后一个信号回答NO ACK
11.2.从IICDS里取出数据
12.清除中断
13.写入0x90到IICSTAT寄存器
14.清除中断
iic.c
/********************************************************************
*名称:iic.c
*作者:D
*时间:2016.03.16
*功能:AT24C08A EEPROM驱动
*********************************************************************/ /********************************************************************
*宏定义
*********************************************************************/
#define GPECON ( (*(volatile unsigned long *)0x56000040) ) //GPE组控制寄存器
#define GPEUP ( (*(volatile unsigned long *)0x56000048) ) //GPE组上拉寄存器 #define INTMSK ( (*(volatile unsigned long *)0x4A000008) ) //中断掩码寄存器
#define SRCPND ( (*(volatile unsigned long *)0X4A000000) ) //中断源请求寄存器
#define INTPND ( (*(volatile unsigned long *)0X4A000010) ) //中断请求寄存器 #define IICCON ( (*(volatile unsigned char *)0x54000000) ) //IIC总线控制寄存器
#define IICSTAT ( (*(volatile unsigned char *)0x54000004) ) //IIC总线状态寄存器
#define IICDS ( (*(volatile unsigned char *)0x5400000C) ) //IIC数据移位寄存器 /********************************************************************
*函数原型
*********************************************************************/
void init_iic();
void byte_write(unsigned char address, unsigned char data);
void random_read(unsigned char address, unsigned char data[], int length);
void iic_irq();
void delay_iic(int count);
void test_iic(); /********************************************************************
*名称:init_iic
*参数:
* none
*返回:
* none
*功能:初始化IIC控制器
*********************************************************************/
void init_iic(){
//配置功能引脚
GPECON &= ~((0x3<<)|(0x3<<));
GPECON |= ((0x2<<)|(0x2<<)); //GPE14[29:28]:IICSCL, GPE14[31:30]:IICSDA GPEUP |= (0x3<<); //GPE[15:15]:The pull up function is disabled //设置中断标志
INTMSK &= ~(<<); //INT_IIC[27]:0
SRCPND |= (<<); //INT_IIC[27]:0
INTPND |= (<<); //INT_IIC[27]:0 //使能中断功能
IICCON |= (<<); //Tx/Rx Interrupt[5]:Enable //设置应答信号
IICCON |= (<<); //Acknowledge generation[7]:Enable //设置时钟周期
IICCON &= ~(<<); //Tx clock source selection[7]:IICCLK = fPCLK / 16 = 50MHz / 16 = 3125KHZ IICCON &= ~(0xF<<); //Transmit clock value[3:0]:0
IICCON |= (0x5<<); //Transmit clock value[3:0]:IICCLK/(IICCON[3:0]+1) = 3125KHz / 16 = 520KHz //打开串行输出
IICSTAT |= (<<); //Serial output[4]:Enable Rx/Tx
} /********************************************************************
*名称:byte_write
*参数:
* address 数据地址
* data 数据内容
*返回:
* none
*功能:按字节写设备
*********************************************************************/
void byte_write(unsigned char address, unsigned char data){
//设置发送模式
IICSTAT |= (0x3<<); //写入设备地址
IICDS = 0xA0; //向从设备写入数据 //打开发送模式
IICSTAT = 0xF0; //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //写入数据地址
IICDS = address; //清除等待标志
IICCON &= ~(<<); //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //写入数据内容
IICDS = data; //清除等待标志
IICCON &= ~(<<); //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //关闭发送模式
IICSTAT = 0xD0; //清除等待标志
IICCON &= ~(<<); //等待结束生效
delay_iic();
} /********************************************************************
*名称:random_read
*参数:
* address 数据地址
* data 数据内容
* length 数据长度
*返回:
* none
*功能:随机读设备
*********************************************************************/
void random_read(unsigned char address, unsigned char data[], int length){
//设置发送模式
IICSTAT |= (0x3<<); //写入设备地址
IICDS = 0xA0; //向从设备写入数据 //打开发送模式
IICSTAT = 0xF0; //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //写入数据地址
IICDS = address; //清除等待标志
IICCON &= ~(<<); //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //关闭发送模式
IICSTAT = 0xD0; //清除等待标志
IICCON &= ~(<<); //等待结束生效
delay_iic(); //设置接收模式
IICSTAT &= ~(0x3<<);
IICSTAT |= (0x2<<); //写入设备地址
IICDS = 0xA1; //从从设备读取数据 //打开接收模式
IICSTAT = 0xB0; //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //空读接收数据
unsigned char temp; temp = IICDS; //清除等待标志
IICCON &= ~(<<); //等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
} //读取接收数据
int i; for(i = ; i < length; i++){
//读取数据内容
data[i] = IICDS; //清除等待标志
IICCON &= ~(<<); //判断接收长度
if(i < (length - )){
//等待应答信号
while( (IICCON & (<<)) == ){
delay_iic();
}
}else{
//发送停止应答
IICCON &= ~(<<);
}
} //关闭接收模式
IICSTAT = 0x90; //清除等待标志
IICCON &= ~(<<); //等待结束生效
delay_iic();
}
/********************************************************************
*名称:iic_irq
*参数:
* none
*返回:
* none
*功能:iic中断服务
*********************************************************************/
void iic_irq(){
//清除中断源请求
SRCPND |= (<<); //INT_IIC[27]:0 //清除中断请求
INTPND |= (<<); //INT_IIC[27]:0
} /********************************************************************
*名称:delay_iic
*参数:
* count 延时次数
*返回:
* none
*功能:延时函数
*********************************************************************/
void delay_iic(int count){
int i, j; for(i = ; i < count; i++){
for(j = ; j < ; j++){
}
}
} /********************************************************************
*名称:test_iic
*参数:
* none
*返回:
* none
*功能:测试AT24C08A
*********************************************************************/
void test_iic(){
//向EEPROM写入数据
int i; for(i = ; i < ; i++){
byte_write(i, i);
} //从EEPROM读取数据
unsigned char buf[]; random_read(, buf, ); //显示数据
for(i = ; i < ; i++){
printf("%d ", buf[i]);
}
printf("\n");
}
[国嵌攻略][153][I2C裸机驱动设计]的更多相关文章
- [国嵌攻略][158][SPI裸机驱动设计]
SPI控制器工作流程 SPI控制器提供2个SPI接口.每个SPI接口有两个通道,分别为TX通道和RX通道.CPU要写数据到FIFO中,先写数据到SPI_TX_DATA寄存器中,这样此寄存器中的内容就会 ...
- [国嵌攻略][156][I2C自编设备驱动设计]
AT24C08的驱动在Linux内核中已经提供,在/drivers/misc/eeprom/at24.c文件中.在对应的probe函数中有一个创建/sys/.../eeprom文件的函数,应用程序通过 ...
- [国嵌攻略][155][I2C用户态驱动设计]
用户态驱动模型 用户态驱动模型首先是一个应用程序,其次是在这个用户程序中通过内核调用来驱动设备. IIC通用驱动代码 IIC通用驱动程序的代码在/drivers/i2c/i2c-dev.c中.一次读操 ...
- [国嵌攻略][152][I2C总线介绍]
IIC电气特性 I2C(inter intergrated circuit)总线是由philps公司开发的两线式串行总线,用于连接微控制器及其外围设备. I2C总线只有两根双向信号线: SDA:ser ...
- [国嵌攻略][136][DM9000网卡驱动深度分析]
网卡初始化 1.分配描述结构,alloc_etherdev 2.获取平台资源,platform_get_resource 2.1.在s3c_dm9k_resource中有相关的资源 2.2.add地址 ...
- [国嵌攻略][137][DM9000网卡驱动编程]
DM9000数据发送 DM9000数据发送函数是在/drivers/net/dm9000.c中的dm9000_start_xmit函数 static int dm9000_start_xmit(str ...
- [国嵌攻略][154][Linux-I2C子系统]
IIC子系统架构 device driver层: 1.device driver,由用户开发. 2.i2c-dev由内核实现,但是需要配合应用模式驱动才能使用. i2c core层: 1.总线驱动,也 ...
- [国嵌攻略][142][LCD驱动程序架构]
LCD裸机驱动回顾 1.LCD初始化 1.1.控制器初始化 1.2.端口初始化 1.3.指明了帧缓冲 2.LCD图形显示 2.1.将图形数据写入帧缓冲 Linux帧缓冲体验 把图片转换成开发板屏对应的 ...
- [国嵌攻略][165][usb下载线驱动设计]
查看USB设备的生产商ID和设备ID 示例: lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 生产商ID是1d ...
随机推荐
- 关于vue 框架与后台框架的混合使用的尝试------转载
这几天我在研究前台框架和后台框架融合的问题,进行了一些尝试; 我前台选择的是 vue,当然也可以选择 react 等其他 mvvm 框架,不过 vue 对于我来说是最熟悉的; 后台话,我选择的是 ph ...
- UWP TextBox私人定制
这次私人定制的是背景透明的TextBox,普通的TextBox在获取焦点后,背景色就变白色了. 下面的代码可以让TextBox的背景始终是透明的. 其实很简单,就修改了 <Setter Prop ...
- IT小白学习Discuz!框架(一)
1.Discuz!是什么? 答:(1).Crossday Discuz! Board(简称 Discuz!)是北京康盛新创科技有限责任公司推出的一套通用的社区论坛软件系统. (2).Crossday ...
- Qt编写QUI皮肤生成器
用Qt写项目写多了,为了满足不同客户的需求,需要定制不同样式的界面,QUI皮肤生成器应运而生.思考这个工具的架构花了一年时间,如何从复杂的配色方案中提取出共性,然后将共性转为具体的QSS文件.思考架构 ...
- Effective Java 第三版——14.考虑实现Comparable接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- mybatis的知识点
mybatis核心配置文件的配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE conf ...
- Python学习_05_条件、循环
条件 和其他语言类似,python中使用if...elif...else来形成分支,支持三目操作符 ?:,python中没有switch,但是缩进的特性让if...elif...else的结构同样便于 ...
- SQLServer:无法生成 SSPI 上下文(Cannot generate SSPI context)
服务器版本:windows Server 2012 R2 数据库版本: SQLServer 2016 +sp1 SQL2016AlwaysOn群集: 由于重启过域控,造成后续的部分服务器也解析不到DN ...
- Sp_Lock
SP_LOCK 其显示信息为: Spid:进程ID号(要发现哪些用户和该spid相连,你就要执行存储过程sp_who) Dbid:数据库ID号(可以在主数据库中的sysdatabases表格中找到它) ...
- HTML与HTML5复习标签汇总
按字母顺序排列 New : HTML5 中的新标签. 标签 描述 <!--...--> 定义注释. <!DOCTYPE> 定义文档类型. <a> 定义锚. < ...