[国嵌攻略][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 ...
随机推荐
- 《跟我学IDEA》五、快捷键(编码利器)
上一篇博文,我们学习了idea的一些模版配置,但是只有模版是不行的,一款编辑器如何能为我们灵活的使用,快捷键的功劳不用多说大家也明白.今天我们就来学习快捷键的配置以及一些常用的快捷键的介绍,为让家能更 ...
- KVM(一):KVM安装
KVM通俗的说就是一台服务器当多台用,详细介绍去百度和谷歌. 首先查看服务器是否支持虚拟化 [root@KVM ~]# grep -E '(vmx|svm)' /proc/cpuinfo --colo ...
- Jmeter+Ant+Jenkins接口自动化测试(一)_环境部署
前言: 2017年最后一个月份,今天抽出时间把之前的一些记录分享出来,也为今年画上个简单的句号吧,无论好与坏,无论成功与失败,简单的记忆,不要留下点点空白. 特别提示: 知识是用来分享的,但是也要尊重 ...
- flask 动手写的接口平台
笔者做的是测试,在群里经常有人讨论,怎么和开发对接怎么难,怎么测接口比较难,开发不愿因写文档等等,是啊,我感觉也是这样,沟通,还有我们应该怎样去学习,去扩充自己,让自己不再受开发所左右, 笔者就像试图 ...
- Java中堆与栈
简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...
- KMP 算法 C++
#include <iostream>#include<string.h>#include<stdio.h>using namespace std; void Co ...
- shell的含义
shell:壳,是操作linux最直接的方式,通过shell中输入命令和linux系统进行交互. shell是一个小盒子,每一个有独立的命名空间,登录后的操作就是一个shell(有可能是bash,zs ...
- vue2.0 如何在hash模式下实现微信分享
最近又把vue的demo拿出来整理下,正好要做"微信分享"功能,于是遇到新的问题: 由于hash模式下,带有"#",导致微信分享的签证无效:当改成history ...
- vue2.0 关于Vue实例的生命周期
什么是生命周期 Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过 ...
- 别纠结mybatis啦,赶紧来瞅瞅吧
自从用了mybatis后,被坑的次数不下于无数次,今天我们就来说说最最头疼的错误,看看有多少人入过这个坑呢. 当程序出现了 Result Maps collection already contain ...