linux下iic(i2c)读写AT24C02

合集下载

24C02数据读写

24C02数据读写

sbit wei1=P1^0;
sbit wei2=P1^1;
/************24C02 数据和时钟端口定义*****************/
sbit sda=P2^7;
sbit scl=P2^6;
/***************八段共阳 LED 编码***********************/ uchar code table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92, 0x82,0xf8,0x80,0x90,0x40};
//---实现功能:
//---开始时从 24C02 中读取秒表信息
//
//---每一秒向 24C02 中写一次信息
//---断电或复位重启后从断点前的那一秒开始计数
//
/****************************************************/
/**************包含头文件****************************/
void respons() //应答 {
uchar i; scl=1; delay(); while((sda==1)&&(i<250))i++; scl=0; delay(); } /************IIC 初始化****************************/ void init() { sda=1;
寻址。 1.总线上数据的有效性
IIC 总线是以串行方式传输数据,从数据字节的最高位开始传送,每一个数据位在 SCL 上都有一个时钟脉冲相对应。 在时钟线高电平期间数据线上必须保持稳定 的逻辑电平状态,高电平为数据 1,低电平为数据 0。只有在时钟线为 低电平时,才允许数据线上的电平状态变化,如图 11-2 所示。 2.总线上的信号 IIC 总线在传送数据过程中共有四种类型信号,它们分别是:开始信号、停止信号、重新开始信号和应答信号。

I2C总线AT24C02存储器读写程序

I2C总线AT24C02存储器读写程序
respons();//写完后调用应答函数
write_byte(date);//在芯片第address位置写date.
respons();//写完后调用应答函数
stop();//I2C结束时钟函数
}
uchar read_add(uchar address)
{
uchar date;
{ start();//I2C开始时钟函数
write_byte(0xa0);//at24c02的固定地址A,1010,AO-A3都接地都为0。
respons();//写完后调用应答函数
write_byte(address);//确定从at24c02的第address位置写数据。
aa=k;
ee=aa*2200;
if(D4==0)
{
delay (100);
if(D4==1)
{
aa++;
delay (1);
init();//写直址,最后低位应为0。
write_add(2,aa);//23为at24c02内部储存地址,0xaa为写到23地址的数据。
#include <reg52.h>
#define uint unsigned int //定义unsigned int 为uint
#define uchar unsigned char //定义unsigned char 为uchar
#define uchar unsigned char //定义unsigned char 为uchar
delay (1);
k=read_add(2);//送到P1口显示。//从23地址读数据

AT24C02的读写

AT24C02的读写
; R3=10100000(命令1010+器件3位地址+读/写。器件地址一个芯片,是000)
; (R4)=片内字节地址
; (R1)=欲写数据存放地址指针
; (R7)=连续写字节数n
EEPW: MOVP1,#0FFH
CLRP1.0;发开始信号
MOVA,R3;送器件地址
ACALLSUBS
MOVA,R4;送片内字节地址
RET
;读串行E2PROM子程序EEPR
;(R1)=欲读数据存放地址指针
;; R3=10100001(命令1010+器件3位地址+读/写。器件地址一个芯片,是000)
;(R4)=片内字节地址
;(R7)=连续读字节数
EEPR: MOVP1,#0FFH
CLRP1.0;发开始信号
MOVA,R3;送器件地址
MOV DPTR,#0600H;定义源数据的位置
LOOP:MOV A,#00H
MOVC A,@A+DPTR
LCALL SDATA
LCALL ACK
JC LOOP
INC DPTR
DJNZ R2,LOOP
LCALL STOP;调用停止子程序
STAR:SETB SDA
SETB SCL
NOP
NOP
NOP
NOP
应答毕sdaret程序中多处调用了delay子程序仅两条nop指令这是为了满足i2c总线上数据传送速率的要求只有当sda数据线上的数据稳定下来之后才能进行读写即scl线发出正脉冲
AT24C02的读写
作者:来源:阅读次数:372
AT24C02是美国ATMEL公司的低功耗CMOS串行EEPROM,它是内含256×8位存储空间,具有工作电压宽(2.5~5.5V)、擦写次数多(大于10000次)、写入速度快(小于10ms)等特点。

IIC总线协议及EEPROMAT24C02

IIC总线协议及EEPROMAT24C02

IIC总线协议及EEPROMAT24C02IIC总线协议及EEPROMAT24C02IIC总线协议是一种串行通信协议,用于在电子设备之间进行数据传输。

它也被称为I2C(Inter-Integrated Circuit)协议。

IIC总线协议由Philips(现在的NXP Semiconductors)在1982年开发,用于同一电路板上的集成电路芯片之间的通信。

IIC总线是一种主从式结构,其中一个设备作为主设备,其他设备作为从设备。

主设备负责控制数据传输和通信的时序。

每个从设备都有一个唯一的地址,主设备根据地址选择要与之通信的从设备。

从设备根据主设备发出的命令来执行特定的操作,例如读取数据或写入数据。

EEPROM是一种可擦写可编程只读存储器(Electrically Erasable Programmable Read-Only Memory),用于存储非易失性数据。

AT24C02是Microchip Technology公司制造的一种EEPROM芯片,具有容量为2Kbit的存储能力。

AT24C02采用了IIC总线协议,因此可以通过IIC总线与其他设备进行通信。

它有一个7位地址寄存器,可以设置其作为IIC总线上的从设备的地址。

在与主设备通信时,主设备发送一个启动条件,然后发送从设备地址,接下来是读写位和数据。

AT24C02根据主设备的指令来执行读取或写入操作。

AT24C02有一个内部的写保护电路,可以保护存储的数据被误写。

它还支持分页写入,即可以一次写入多个字节的数据,从而提高写入效率。

总结:IIC总线协议是一种用于串行通信的协议,适用于设备之间的数据传输。

AT24C02是一种采用IIC总线协议的EEPROM芯片,具有2Kbit的存储容量。

它通过主设备的控制来进行读写操作,同时具有写保护和分页写入等特性。

I2C总线协议AT24c02程序

I2C总线协议AT24c02程序

I2C总线协议(AT24c02)程序主:STC89C54从:AT24C02电路图时序图下面是代码#include ;#define uchar unsigned char#define addr_x 0xae//写#define addr_d 0xaf//读sbit sda = P2^1;//数据管脚sbit scl = P2^0;//时钟管脚bit ack;void DelayUs2x(unsigned char t)//延时1{while(--t);}void DelayMs(unsigned char t)//延时2{ while(t--){ //大致延时1mS DelayUs2x(245); DelayUs2x(245);}}void delay() //延时大于4μs{;;}void i2_qs()//起始信号{sda = 1;//拉高数据scl = 1;//拉高时钟delay();//延时大于 4μssda =0;//拉低数据产生起始信号(下降沿)delay();//延时大于 4μsscl = 0;//拉低时钟delay();//延时大于4μs}void i2_tz()//停止信号{sda = 0;//拉低数据scl = 1;//拉高时钟delay();//延时大于 4μssda = 1;//拉高时钟产生结束信号(上升沿)delay();//延时大于4μs}void i2_ack(bit _ack)//入口产生 0 ack 1nak{sda = _ack;//ack或者nakscl = 1;//拉高时钟delay();//延时大于 4μsscl = 0;//拉低时钟delay();//延时大于 4μs}void i2_fs(uchar Data) //发送8位数据{uchar i;for(i=0;i<8;i++)//8位计数{Data <<= 1;//把最高位移送到进制标志位中(CY)sda = CY;//把进制位中的数据赋值给数据线scl = 1;//拉高时钟delay();//延时大于 4μsscl = 0;//拉低时钟//这里}//下面代码是接收ACK的代码delay();//延时大于4μssda = 1;//拉高数据准备接收ACKscl = 1;//拉高时钟产生稳定的有效的数据(相对的)if(sda==1)//确认接收的是ACK还是NAKack = 0;//ackelseack = 1;//nakscl = 0;//拉低时钟delay();//延时大于 4us}uchari2_js()//接收8位数据{uchar i,Data = 0;sda = 1;//使能内部上拉,准备读取数据for(i=0;i<8;i++)//8位计数器{Data <<= 1;//移出数据的最高位scl = 1;//拉高时钟delay();//延时大于 4usData |= sda;//接收数据scl = 0;//拉低时钟delay();//延时大于 4us}return Data;}void i2_sj_x(uchar addr,uchar Data)//往设备内写入数据(参数 1、寄存器地址 2、写入的数据){i2_qs();//起始信号i2_fs(addr_x);//设备地址+写信号i2_fs(addr);//寄存器内部地址i2_fs(Data);//写入设备的数据i2_tz();//停止信号}uchar i2_sj_d(uchar addr)//读取数据(参数寄存器地址){ucharData;i2_qs();//起始信号i2_fs(addr_x);//设备地址+写信号i2_fs(addr);//寄存器内部地址i2_qs();//起始信号i2_fs(addr_d);//设备地址+读信号Data =i2_js();//读取数据i2_ack(0);//ACK应答i2_tz();//停止信号return Data;//返回读取的数据}voidmain(void){uchar dat;i2_sj_x(3,0x0f); //数据写入24c02DelayMs(50);dat = i2_sj_d(3); //从24c02中读取数据P1 = dat;//使用8个LED显示读出的数据while(1){;}}以上代码只是简单的实现I2C总线的读写。

I2C总线编程实例(k1-k4:写入、读取、加+、清零)【EEPROM-AT24C02】

I2C总线编程实例(k1-k4:写入、读取、加+、清零)【EEPROM-AT24C02】

I2C总线编程实例(k1-k4:写⼊、读取、加+、清零)【EEPROM-AT24C02】(1)AT24C02是⼀种EEPROM元器件,是⼀种只读寄存器,断电保持,可保存数据100年, 是⼀种可擦除读写的芯⽚,相当于ROM硬盘,在下⾯实验中充当从机⾓⾊;(2)51在下⾯实验中充当主机⾓⾊;(3)在IIC总线标准协议上,进⾏51单⽚机(主机)和AT24C02(从机)的相互读写数据的操作。

⼩结:51单⽚机和各种EEPROM芯⽚之间可以通过IIC总线标准协议进⾏数据交互(通信)的。

实验:四个独⽴按键对应四个不同的功能,k1:将数据写⼊单⽚机,断电保存k2:读取上次保存的数据,断电后仍可读取上次保存的数据k3:当前数据+1k4:当前数据清零------------------------------------------------------------- 采⽤多⽂件的框架模式 -------------------------------------------------------------i2c.h:/*这个⽂件进⾏宏定义:定义I2C串⾏总线的相关数据端⼝、⽅法函数,以及定义⼀些使⽤频率较⾼的元素*/#ifndef _I2C_H_ // 如果没有定义宏#define _I2C_H_ // 定义⼀个宏// 需要⽤到51单⽚机的管脚,所以需要引⼊库⽂件#include <reg52.h>// 查单⽚机原理图可知(其中,SCL是时钟线,SDA是数据线)sbit SCL=P2^1;sbit SDA=P2^0;/* 相关函数 */// I2C的起始信号函数void I2cStart();// I2C的终⽌信号函数void I2cStop();// I2C发送(写⼊)字节函数,成功返回1,失败返回0unsigned char I2cSendByte(unsigned char dat);// I2C接收(读取)字节函数,返回读取的数据unsigned char I2cReadByte();// AT24C02芯⽚的写⼊数据函数void At24c02Write(unsigned char addr, unsigned dat);// AT24C02芯⽚的读取数据函数,返回读取的数据unsigned char At24c02Read(unsigned char addr);#endif // 结束i2c.c:/* 这个⽂件专门针对I2C模块的编程,其他模块可以新建另外⼀个⽂件 */#include <i2c.h> // 引⼊I2C的库⽂件/******************************************************************************** 函数名 : Delay10us()* 函数功能 : 延时10us* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/void Delay10us() //误差 0usunsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);}/******************************************************************************** 函数名 : I2cStart()* 函数功能 : 起始信号:在SCL时钟信号在⾼电平期间SDA信号产⽣⼀个下降沿* 输⼊ : ⽆* 输出 : ⽆* 备注 : 起始之后SDA和SCL都为0,表⽰总线被主机占⽤*******************************************************************************/void I2cStart(){// 根据各个单⽚机的时序图来写SDA=1;Delay10us();SCL=1;Delay10us(); // 建⽴时间是SDA保持时间>4.7usSDA=0;Delay10us(); // 保持时间是>4usSCL=0;Delay10us();}/******************************************************************************** 函数名 : I2cStop()* 函数功能 : 终⽌信号:在SCL时钟信号⾼电平期间SDA信号产⽣⼀个上升沿* 输⼊ : ⽆* 输出 : ⽆* 备注 : 结束之后保持SDA和SCL都为1;表⽰总线处于空闲状态*******************************************************************************/void I2cStop(){// 根据各个单⽚机的时序图来写SDA=0;Delay10us();SCL=1;Delay10us(); // 建⽴时间是SDA保持时间>4.7usSDA=1;Delay10us(); // 保持时间是>4us}/******************************************************************************** 函数名 : I2cSendByte(unsigned char dat)* 函数功能 : 通过I2C发送⼀个字节。

I2C总线at24c02芯片使用说明

I2C总线at24c02芯片使用说明

325密码储存电路密码储存电路采用l2C总线at24c02存储芯片存放密码,可实现断电密码不消失,at24c02存储芯片可长期存储信息,可上百万次以上重新擦写。

2.4.3 I 2C总线密码存储芯片at24c02介绍S-I&ad TSSOP图2-3 at24c02 引脚图(1)引脚功能介绍及相关知识WP写保护引脚,将该引脚接VCC U PROM就实现写保护(只读)。

引脚接地或悬空,可以对器件进行读写操作。

SCL串行时钟引脚,串行输入输出时该引脚用于输入时钟。

SDA串行数据输入输出引脚,用来输入输出数据,该引脚为射极开路输出,需接上拉电阻。

(2) |2C总线协议只有总线非忙时才被允许进行数据传送,在传送时,当时钟线为高电平,数据线必须为固定状态,不允许有跳变。

时钟线为高电平时数据线的任何电平变化将被当作总线的启动或停止条件。

(3)起始条件起始调教必须在所有操作命令之前发送。

时钟线保持高电平期间,数据线电平从高到低跳变作为I2C总线的启动信号。

CAT24Cxx>一直监视SDA和SCL电平信号,直到条件满足时才响应。

(4) 停止条件时钟线保持高电平期间,数据线电平从低到高跳变作为l 2C 总线的停止信号。

(5) 器件地址的约定主器件在发送启动命令后开始传送数据,主器件发送相应的从器件地址, 8位从器件地址的高四位固定为1010,接下来的3位用来定义存储器的地址,对 于CAT24C021/022这三位无意义,对于 CAT24C41/042接下来的2位无意义, 第三位是地址高位,CAT24C081/082中,第一位无意义,后两位表示地址高位。

最后一位为读写控制位,“ 1”表示对从器件进行读写操作,“ 0 ”表示写操 作。

在主器件发送启动命令和一字节从器件地址后,如果与从器件地址吻合, CAT24C02各发送一个应答信号,然后再根据读/写控制为进行读或写操作。

(6) 应答信号每次数据传送成功后,接收器件将发送一个应答信号。

IIC总线24C02读写

IIC总线24C02读写

实验说明:T24C01A/AT24C02为I2C总线型EEPROM存储器,容量为1K/2K位(128/256*8),前读/写时序遵循I2C总线协议标准。

A T24C01A/A T24C02内部设有一个控制寄存器,其每一位的含义如下:Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit01 0 1 0 A2 A1 A0 R/W其中A2/A1/A0用于选择总线上待访问的I2C器件,R/W=1读操作,R/W=0写操作;从上述时序可以看出,I2C总线上最多可以扩展23=8片同样的1K/2K容量EEPROM存储器或者可以扩展1片容量为16K Bits的EEPROM存储器。

如果扩展8片2K以内容量的EEPROM 存储器,每片存储器将对应一个地址,这个由于实验仪上的A T24C01A/AT24C02的A2/A1/A0引脚全部接地,等效为实验仪上的AT24C01A/AT24C02的地址为0,所以在实验中读写控制字分别为:0xa1/0xa0实验要求利用实验仪上的I2C总线器件AT24C01A/AT24C02,编写I2C总线读写程序并自行验证程序的正确性。

c语言:/* 实验四十二IIC总线24C02读写*//* C51 */#include <reg51.h>#include <intrins.h>/* **********************************************************24C01/02 为IIC总线EEPROM存储器, 容量为1k位(128 * 8)************************************************************//* **********************************************************EEPROM控制字节格式:[1, 0, 1, 0, A2, A1, A0, (R/W)], 其中R/W=1读,R/W=0写;由于实验仪上的AT24C01A(AT24C02) 的A2/A1/A0全部接地,所以读/写控制字分别为:0xa1/0xa0************************************************************/#define WriteDeviceAddress 0xa0#define ReadDeviceAddress 0xa1/******************IIC器件驱动引脚定义**********************/sbit SCL = P1^0;sbit SDA = P1^1;/***********************简单延时****************************/void DelayMs(unsigned int number){unsigned char temp = 112;while(number--!=0){while(temp--!=0){}}}/*********************启动IIC总线***************************/void Start() {SDA = 1;SCL = 1;SDA = 0;SCL = 0;}/*********************停止IIC总线***************************/void Stop() {SCL = 0;SDA = 0;SCL = 1;SDA = 1;}/***********************请求相应****************************/void Ack() {SDA = 0; /*从器件响应信号将SDA线拉到低电平*/SCL = 1;SCL = 0;SDA = 1; /*响应结束,SDA回到高电平继续下一个传送周期*/ }/*******************不对IIC总线产生应答*********************/void NoAck() {SDA = 1; /*从机不响应时,数据线保持高电平*/SCL = 1;SCL = 0;}/**********************检查应答位***************************/bit TestAck() {SDA = 1;SCL = 1;CY = SDA;SCL = 0;return(CY); /*CY=0表应答*/}【关于I2C的检查应答信号的程序】unsigned char I2C_CheckAck(void){unsigned char i;unsigned char Ack=1;I2C_SDA=1;DelayUs(I2C_DELAY);I2C_SCL=1;DelayUs(I2C_DELAY);for(i=0;i<10;i++){Ack=I2C_SDA;if(!Ack){I2C_SCL=0;return 1;}}I2C_Stop();return 0;}/********************向IIC总线写数据************************/ bit Write8Bit(unsigned char input){unsigned char temp;for(temp = 8; temp != 0; temp--){SDA = (bit)(input&0x80); /*取Input最高位*/SCL = 1;SCL = 0;input = input<<1; /*input左移输入下一位*/ }return(0);}/****************从IIC总线上读数据子程序********************/unsigned char Read8Bit(){unsigned char temp, rbyte=0;for(temp=8;temp!=0;temp--){SCL=1;rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA)); /*循环结束把8位的SDA(串行的)读成了一个8位的数放到rbyte中*/SCL=0;}return(rbyte);}/*******************向EEPROM中写入数据块********************/void AT24C02WriteBlock(unsigned char *Wdata, unsigned char RomAddress, unsigned char number){if(number > 8)number %= 8; /*对于24C02, 一个页为8字节,所以最大的块写操作字节数为8*/ Start();Write8Bit(WriteDeviceAddress); //总线上器件地址TestAck();Write8Bit(RomAddress); //器件内部要写入地址,有时将此处省略默认从00开始TestAck();for(;number!=0;number--){Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/**************从EEPROM中读出数据块到指定RAM中**************/void AT24C02ReadBlock(unsigned char *RamAddress, unsigned char RomAddress, unsigned char bytes){EA = 0; //单片机读操作限制在外部ROMStart();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start(); //重新启动总线Write8Bit(ReadDeviceAddress);TestAck();while(bytes!=1){*RamAddress = Read8Bit();Ack();RamAddress++;bytes--;}*RamAddress = Read8Bit();NoAck();Stop();}/*****************向EEPROM中写入单字节数据******************/ void AT24c02WriteByte(unsigned char WriteData, unsigned char RomAddress) { Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Write8Bit(WriteData);TestAck();Stop();DelayMs(10);}/************从EEPROM中读出单字节数据到指定RAM中************/ unsigned char AT24c02ReadByte(unsigned char RomAddress) {unsigned char ReadData;Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDeviceAddress);TestAck();ReadData = Read8Bit();NoAck();Stop();return(ReadData);}void main(void){unsigned char i;unsigned char WriteBuff[8], ReadBuff[8];/* 读写缓冲初始化*/for(i = 0; i < 8; i++){WriteBuff[i] = 0x55 + i;ReadBuff[i] = 0xff;}/* 从地址0开始按字节方式写入8个数据'0' */for(i = 0; i < 8; i++){A T24c02WriteByte(0, i);}/* 按字节方式读出数据*/for(i = 0; i < 8; i++) {ReadBuff[i] = AT24c02ReadByte(i);}/* 按写Page方式从地址0开始写入WriteBuff指向的8个数据*/ A T24C02WriteBlock(WriteBuff, 0x00, 8);/* 按连续读取方式读出从地址0开始的8个数据*/A T24C02ReadBlock(ReadBuff, 0x00, 8);while(1);}汇编语言:; 实验四十二IIC总线24C02读写; ASM51; ********************************************************** ; 24C01/02 为IIC总线EEPROM存储器, 容量为1k位(128 * 8); **********************************************************; ********************************************************** ; EEPROM控制字节格式:; [1, 0, 1, 0, A2, A1, A0, (R/W)], 其中R/W=1读,R/W=0写;; 由于实验仪上的AT24C01A(AT24C02) 的A2/A1/A0全部接地, ; 所以读/写控制字分别为:0xa1/0xa0; ********************************************************** WriteDeviceAddress equ 0a0hReadDeviceAddress equ 0a1h; ******************IIC器件驱动引脚定义********************* SCL equ P1.0SDA equ P1.1; *******************读写数据缓冲定义*********************** ReadBuff equ 40hWriteBuff equ 48hRWLength equ 30hRomAddress equ 31horg 0000hljmp Mainorg 0100h; ***********************简单延时*************************** DelayMs:push 06nopDelayMsLoop2:mov r6, #0ffhDelayMsLoop1:djnz r6, DelayMsLoop1djnz acc, DelayMsLoop2pop 06ret; ********************启动IIC总线*************************** Start:setb SDAsetb SCLclr SDAclr SCLret; ********************停止IIC总线*************************** Stop:clr SCLclr SDAsetb SCLsetb SDAret; **********************请求相应**************************** Ack:clr SDAsetb SCLclr SCLsetb SDAret; ******************不对IIC总线产生应答********************* NoAck:setb SDAsetb SCLclr SCLret; *********************检查应答位*************************** TestAck:setb SDAsetb SCLmov C, SDAclr SCLnopnopnopret; *******************向IIC总线写数据************************Write8Bit:push 07mov r7, #8Write8BitLoop:rlc amov SDA, Csetb SCLclr SCLnop ; 此处建议加入几个NOP指令降低MCU对器件操作的速度nopnopdjnz r7, Write8BitLooppop 07ret; ***************从IIC总线上读数据子程序********************Read8Bit:push 07clr amov r7, #8Read8BitLoop:clr Csetb SCLmov C, SDArlc aclr SCLnop ; 此处建议加入几个NOP指令降低MCU对器件操作的速度nopnopdjnz r7, Read8BitLooppop 07ret; ******************向EEPROM中写入数据块********************AT24C02WriteBlock:clr eamov r0, #WriteBuffinc RWLengthanl RWLength, #0f0h ;对于24C02, 一个页为8字节,所以最大的块写操作字节数为8*/mov r7, RWLengthcall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckAT24C02WriteBlockLoop:mov a, @r0call Write8Bitcall TestAckinc r0djnz r7, AT24C02WriteBlockcall Stopmov a, #10call DelayMsret; *************从EEPROM中读出数据块到指定RAM中************** AT24C02ReadBlock:clr eamov r0, #ReadBuffmov r7, RWLengthcall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckcall Startmov a, #ReadDeviceAddresscall Write8Bitcall TestAckAT24C02ReadBlockLoop:call Read8Bitmov @r0, acall Ackinc r0djnz r7, AT24C02ReadBlockcall NoAckcall Stopret; ****************向EEPROM中写入单字节数据****************** AT24c02WriteByte:clr eacall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckmov a, @r0call Write8Bitcall TestAckcall Stopmov a, #10call DelayMsret; ***********从EEPROM中读出单字节数据到指定RAM中************ AT24c02ReadByte:clr eacall Startmov a, #WriteDeviceAddresscall Write8Bitcall TestAckmov a, RomAddresscall Write8Bitcall TestAckcall Startmov a, #ReadDeviceAddresscall Write8Bitcall TestAckcall Read8Bitmov @r0 ,acall NoAckcall StopretSetReadBuff:mov r0, #ReadBuffmov r7, RWLengthSetReadBuffLoop:mov @r0, ainc r0djnz r7, SetReadBuffLoopretSetWriteBuff:mov r0, #WriteBuffmov r7, RWLengthSetWriteBuffLoop:mov @r0, ainc r0djnz r7, SetWriteBuffLoopretMain:mov SP, #60h; 读写缓冲初始化mov a, #00mov RWLength, #8call SetReadBuffmov a, #00mov RWLength, #8call SetWriteBuff; 写缓冲初始化mov r0, #WriteBuffmov r7, #8mov a, #55hInitWriteBuffLoop:mov @r0, ainc ainc r0djnz r7, InitWriteBuffLoop; 从地址0开始按字节方式写入8个数据'0' mov RomAddress, #0mov r7, #8mov r0, #WriteBuffWriteLoop:call AT24c02WriteByteinc RomAddressinc r0djnz r7, WriteLoop; 按字节方式读出数据mov RomAddress, #0mov r7, #8mov r0, #ReadBuffReadLoop:call AT24c02ReadByteinc RomAddressinc r0djnz r7, ReadLoop; 按写Page方式从地址0开始写入WriteBuff指向的8个数据mov RomAddress, #0mov RWLength, #8mov r0, #WriteBuffcall AT24C02WriteBlock; 按连续读取方式读出从地址0开始的8个数据mov RomAddress, #0mov RWLength, #8mov r0, #ReadBuffcall AT24C02ReadBlockjmp $end。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/jammy_lee/
linux下iic(i2c)读写AT24C02
linux驱动2010-02-09 16:02:03 阅读955 评论3 字号:大中小订阅
linux内核上已有iic的驱动,因此只需要对该iic设备文件进行读写则能够控制外围的iic器件。

这里以AT24C02为对象,编写一个简单的读写应用程序。

iic设备文件在我的开发板上/dev/i2c/0 ,打开文件为可读写。

AT24C02的器件地址为0x50 ,既是iic总线上从器件的地址,每次只读写一字节数据。

/************************************************************/
//文件名:app_at24c02.c
//功能:测试linux下iic读写at24c02程序
//使用说明: (1)
// (2)
// (3)
// (4)
//作者:jammy-lee
//日期:2010-02-08
/************************************************************/
//包含头文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
//宏定义
#define Address 0x50 //at24c02地址
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_SLAVE 0x0703 //IIC从器件的地址设置
#define I2C_BUS_MODE 0x0780
typedef unsigned char uint8;
uint8 rbuf[8] = {0x00}; //读出缓存
uint8 wbuf[8] = {0x01,0x05,0x06,0x04,0x01,0x01,0x03,0x0d}; //写入缓存int fd = -1;
//函数声明
static uint8 AT24C02_Init(void);
static uint8 i2c_write(int fd, uint8 reg, uint8 val);
static uint8 i2c_read(int fd, uint8 reg, uint8 *val);
static uint8 printarray(uint8 Array[], uint8 Num);
//at24c02初始化
static uint8 AT24C02_Init(void)
{
fd = open("/dev/i2c/0", O_RDWR); //允许读写
if(fd < 0)
{
perror("Can't open /dev/nrf24l01 \n"); //打开iic设备文件失败
exit(1);
}
printf("open /dev/i2c/0 success !\n"); //打开iic设备文件成功
if(ioctl(fd, I2C_SLAVE, Address)<0) { //设置iic从器件地址printf("fail to set i2c device slave address!\n");
close(fd);
return -1;
}
printf("set slave address to 0x%x success!\n", Address);
if(ioctl(fd, I2C_BUS_MODE, 1)<0) //设置iic总线模式printf("set bus mode fail!\n");
else
printf("set bus mode ok!\n");
return(1);
}
/*
uint8 AT24C02_Write(uint8 *nData, uint8 Reg, uint8 Num)
{
write(fd, &Reg, 1); //
usleep(100); //延时100us
write(fd, nData, Num);
usleep(1000*4); //延时4ms
return(1);
}
uint8 AT24C02_Read(uint8 nData[], uint8 Reg, uint8 Num) {
write(fd, &Reg, 1);
usleep(100); //延时100us
read(fd, nData, Num);
usleep(1000*4); //延时4ms
return(1);
}
*/
//at24c02写入一字节
static uint8 i2c_write(int fd, uint8 reg, uint8 val)
{
int retries;
uint8 data[2];
data[0] = reg;
data[1] = val;
for(retries=5; retries; retries--) {
if(write(fd, data, 2)==2)
return 0;
usleep(1000*10);
}
return -1;
}
//at24c02读取一字节
static uint8 i2c_read(int fd, uint8 reg, uint8 *val)
{
int retries;
for(retries=5; retries; retries--)
if(write(fd, &reg, 1)==1)
if(read(fd, val, 1)==1)
return 0;
return -1;
}
//输出数组
static uint8 printarray(uint8 Array[], uint8 Num) {
uint8 i;
for(i=0;i<Num;i++)
{
printf("Data [%d] is %d \n", i ,Array[i]);
}
return(1);
}
//主函数
int main(int argc, char *argv[])
{
int i;
AT24C02_Init();
usleep(1000*100);
for(i=0; i<sizeof(rbuf); i++)
if(i2c_read(fd, i, &rbuf[i]))
break;
printarray(rbuf ,8);
printf("Before Write Data \n"); sleep(1);
for(i=0; i<sizeof(rbuf); i++)
if(i2c_write(fd, i, wbuf[i]))
break;
printarray(wbuf ,8);
printf("Writing Data \n");
sleep(1);
for(i=0; i<sizeof(rbuf); i++)
if(i2c_read(fd, i, &rbuf[i]))
break;
printarray(rbuf ,8);
printf("After Write Data \n");
close(fd);
}。

相关文档
最新文档