用c语言实现24LC256读写.docx
- 文档编号:7588972
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:19
- 大小:19.80KB
用c语言实现24LC256读写.docx
《用c语言实现24LC256读写.docx》由会员分享,可在线阅读,更多相关《用c语言实现24LC256读写.docx(19页珍藏版)》请在冰豆网上搜索。
用c语言实现24LC256读写
用c语言实现24LC256读写
用c语言实现24LC256读写(非软件模拟方式)
24LC256工作电压为2.5V~5.5V,容量为32K×8bit,为两线串行接口总线,标准与I2CTM兼容。
SCL为24LC256的时钟输入管脚,SDA为其串行地址/数据输入/数据输出管脚。
24LC256提供读顺序地址内容的操作方式,其内部的地址指针在每次读操作完成之后加1,此地址指针允许在一次读操作期间,连续顺序地读出整个存储器的内容。
#include
unsignedchari=0;
unsignedcharreceive=0x00;
voidi2c_start()
{
SEN=1; //启动
do{
}while(SSPIF==0);
SSPIF=0;
}
voidi2c_stop()
{
PEN=1; //产生停止条件
do{
;
}while(SSPIF==0);
SSPIF=0;
}
voidi2c_restart()
{
RSEN=1;//启动,反复启动
do{
;
}while(SSPIF==0);
SSPIF=0;
}
voidi2c_dataout() //数据发送等待过程
{
do{
;
}while(SSPIF==0);
SSPIF=0;
}
voidi2c_datain() //读取24LC256时,不是读的最后一个字节时使用
{
RCEN=1;
do{
;
}while(SSPIF==0);
SSPIF=0;
receive=SSPBUF;
ACKDT=0;
ACKEN=1;
do{
;
}while(SSPIF==0);
SSPIF=0;
}
voidi2c_datainlast() //读取最后一个字节,或只读取24lc256中一个字节
{
SSPIF=0;
RCEN=1;
do{
;
}while(SSPIF==0);
SSPIF=0;
receive=SSPBUF;
ACKDT=1;
ACKEN=1;
do{
;
}while(SSPIF==0);
SSPIF=0;
}
voidi2c_error()
{
i2c_stop();
return;
}
voidwrite(unsignedintaddr,unsignedchardata,unsignedintn)//向iic写入一字节数据地址,数据,字节个数
{
i2c_start();
SSPBUF=0xA0;//EEPROM寻址码和写操作命令码
i2c_dataout();//发送
if(ACKSTAT)
i2c_error(); //无应答,错误!
elseif(!
ACKSTAT)
SSPBUF=addr/256;
//高eeaddr/256,取eeprom数据地址高字节
i2c_dataout();//发送
if(ACKSTAT)
i2c_error(); //无应答,错误!
elseif(!
ACKSTAT)
SSPBUF=addr%256;//低eeaddr%256,取eeprom数据地址低字节
i2c_dataout();//发送
for(i=0;i { if(ACKSTAT)//应答 i2c_error();//无应答,错误! elseif(! ACKSTAT) SSPBUF=data;//eedata 入eeprom的数据 i2c_dataout();//发送 } if(ACKSTAT)//应答 i2c_error(); i2c_stop(); //产生停止位,启动eeprom内部些过程 do{ i2c_start(); SSPBUF=0xA0; i2c_dataout(); i2c_stop(); if(! ACKSTAT)break; }while(ACKSTAT); } unsignedintcurrent_read(void)//currentaddressreadok! { i2c_start(); SSPBUF=0xA1;//寻址命令码0xA0和读命令 i2c_dataout(); if(ACKSTAT)//应答 i2c_error(); elseif(! ACKSTAT) i2c_datainlast(); i2c_stop(); return((unsignedint)receive); } unsignedintrandom_read(unsignedinteepromaddress) { i2c_start(); SSPBUF=0xA0;//EEPROM寻址码和写操作命令码 i2c_dataout();//发送 if(ACKSTAT) i2c_error(); //无应答,错误! elseif(! ACKSTAT) SSPBUF=eepromaddress/256; //高eeaddr/256,取eeprom数据地址高字节 i2c_dataout();//发送 if(ACKSTAT) i2c_error(); //无应答,错误! elseif(! ACKSTAT) SSPBUF=eepromaddress%256;//低eeaddr%256,取eeprom数据地址低字节 i2c_dataout();//发送 if(ACKSTAT) i2c_error(); //无应答,错误! elseif(! ACKSTAT) i2c_restart(); SSPBUF=0xA1;//寻址命令码0xA0和读命令 i2c_dataout(); if(ACKSTAT)//应答 i2c_error(); elseif(! ACKSTAT) i2c_datainlast(); i2c_stop(); return((unsignedint)receive); } voidi2c_init() { SSPSTAT=0x00; TRISC=0xD8; SSPADD=19; SSPIE=0; SSPCON=0x28; } 实例1 /* 51系列单片机在使用时,有时需要模拟I2C总线_nbsp; */ /* 这里举出一个实例(读写串行EEPROM芯片at24C02_nbsp; */ /************************************************************************/ /*Name: AT24C02存储器的读写程序,用到I2C总线,含相对独立的I2C总线读写函数*/ /*Language: C51单片机编程语言 */ /*Platform: Win98,IntelCeleron433Processor,伟福仿真器,仿真8751 */ /*Author: StephenZhu javasdk@ */ /*Date: 2003广朿1旿5朿2旿5朿9旿nbsp; */ /*Version: 1.1.1 */ /*Others: None */ /************************************************************************/ #include #include #include #defineDELAY_TIME60/*经实验,不要小于50! 否则可能造成时序混乱*/ #defineTRUE1 #defineFALSE0 sbitSCL=P1^7;/*假设由P1.7和P1.6控制*/ sbitSDA=P1^6; /**********Definition 函数定义************/ voidDELAY(unsignedintt)/*延时函数*/ { while(t! =0) t--; } voidI2C_Start(void) { /*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/ SDA=1; SCL=1; DELAY(DELAY_TIME); SDA=0; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); } voidI2C_Stop(void) { /*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/ SDA=0; SCL=1; DELAY(DELAY_TIME); SDA=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); } voidSEND_0(void) /*SENDACK*/ { /*发逿,在SCL为高电平时使SDA信号为低*/ SDA=0; SCL=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); } voidSEND_1(void) { /*发逿,在SCL为高电平时使SDA信号为高*/ SDA=1; SCL=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); } bitCheck_Acknowledge(void) { /*发送完一个字节后检验设备的应答信号*/ SDA=1; SCL=1; DELAY(DELAY_TIME/2); F0=SDA; DELAY(DELAY_TIME/2); SCL=0; DELAY(DELAY_TIME); if(F0==1) returnFALSE; returnTRUE; } voidWriteI2CByte(charb)reentrant { /*向I2C总线写一个字芿/ chari; for(i=0;i<8;i++) if((b< SEND_1(); else SEND_0(); } charReadI2CByte(void)reentrant { /*从I2C总线读一个字芿/ charb=0,i; for(i=0;i<8;i++) { SDA=1; /*释放总线*/ SCL=1; /*接受数据*/ DELAY(10); F0=SDA; DELAY(10); SCL=0; if(F0==1) { b=b<<1; b=b|0x01; } else b=b<<1; } returnb; } /**********以下为读冿4c02的函敿*********/ voidWrite_One_Byte(charaddr,charthedata) { bitacktemp=1; /*writeabytetomem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); WriteI2CByte(thedata);/*thedata*/ acktemp=Check_Acknowledge(); I2C_Stop(); } voidWrite_A_Page(char*buffer,charaddr) { bitacktemp=1; bitwrtmp; inti; /*writeapagetoat24c02*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); for(i=0;i<7;i++) { WriteI2CByte(buffer[i]); if(! Check_Acknowledge()) { I2C_Stop(); } } I2C_Stop(); } charRead_One_Byte(charaddr) { bitacktemp=1; charmydata; /*readabytefrommem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); I2C_Start(); WriteI2CByte(0xa1); acktemp=Check_Acknowledge(); mydata=ReadI2CByte(); acktemp=Check_Acknowledge(); returnmydata; I2C_Stop(); } voidRead_N_Bytes(char*buffer,charn,charaddr) { bitacktemp=1; inti=0; /*read8bytesfrommem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); I2C_Start(); WriteI2CByte(0xa1); acktemp=Check_Acknowledge(); for(i=0;i { buffer[i]=ReadI2CByte(); if(i! =n-1) SEND_0(); /*发送应筿/ else SEND_1(); /*发送非应答*/ } I2C_Stop(); } voidmain() { inti; charmybyte; charmyarray[8]; charmyarray2[8]; charrdarray[16]; for(i=0;i<8;i++) { myarray[i]=i; myarray2[i]=i+0x08; } Write_One_Byte(0x20,0x28); Write_A_Page(myarray,0x10); Write_A_Page(myarray2,0x18); mybyte=Read_One_Byte(0x20); Read_N_Bytes(rdarray,16,0x10); } ================================================================================================== 实例2 /**********************************I2C总线驱动************************************* 模块名: I2C总线驱动 型号: I2C 创建人: 陈曦 日期_005-6-15 修改人: 陈曦 日期_005-6-19 功能描述_/p> 此模块包括发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,能很 方便的与用户程序进行连接并扩展? br> 需要注意的是,函数是采用延时方法产甿SCL脉冲,对高晶振频率要做一定的修改! ! 在写E2PROM的时候一定要延时! ! _br> 说明_/p> 1us机器周期,晶振频率要小于12MHz 返回1则操作成功,返回0则操作失败? br> sla为器件从地址,suba为器件子地址? /p> *************************************************************************************/ #include "AT89X52.h" #include #define _Nop() _nop_() //定义空指仿/p> sbit SDA=P1^3; //模拟I2C数据传输使br>sbit SCL =P1^2; //模拟I2C时钟控制使/p> bit bdata I2C_Ack; //应答标志使/p> /************************************I2C_Start************************************ 函数名: void I2C_Start() 入口_br> 出口_/p> 功能描述: 启动I2C总线,即发送I2C初始条件 调用函数_nbsp; 全局变量_/p> 创建者: 陈曦 日期_005-6-15 修改者: 日期_/p> **********************************************************************************/ void I2C_Start() { SDA =1; //发送起始条件的数据信号 _Nop(); SCL =1; _Nop();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 实现 24 LC256 读写