24c04读写程序详解

24c04读写程序详解 scl bit p1.7;定义24c02的串行时钟线 climberwin 2005.8.4
sda bit p1.6;定义24c02的串行数据线
org 00h
start:
mov r1,#20h ; 数据保存地址
mov r7,#120 ; 取数据的个数
;;**********************************
call first ;开始命令
mov a,#0a0h ;写器件地址
call subs
;;**********************************
mov a,#00h ;所要读的器件的地址
call subs
;;**********************************
call first ;开始命令
mov a,#0a1h ;开始读数据
call subs
;;**********************************
win: call subr
mov @r1,a
inc r1
djnz r7,win
clr sda
call delay
setb scl
call delay
setb sda
jmp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
subr: mov r0,#08h
loop2: setb scl
call delay
mov c,sda
rlc a
clr scl
call delay
djnz r0,loop2
cjne r7,#00h,low1 ;改
setb sda
jmp climber
low1: clr sda
climber:call delay
setb scl
call delay
clr scl
call delay
setb sda
ret
subs: mov r5,#08h
loop: clr scl
rlc a
mov sda ,c
nop
setb scl
call delay
djnz r5,loop
clr scl
call delay
setb scl
rep: mov c, sda
jc rep
clr scl
ret
delay: nop
nop
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
first: setb sda
setb scl
call delay
clr sda
call delay
clr scl ;开始传数据
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
end
先把下面的#define numbyte 改为对应ic型号
调用write_flash()和read_flash()前,先把page07填好对应的页数,下面的
函数声明处有说明
需要在主程序处定义一些参数,如下:
bit f_rom; //eprom应答标志,=1不应答
uchar xdata epromerr; //用来统计写入出错的次数
uint xdata epadd; //用来作为rom目标写入的首地址,要进行计算
uchar xdata page07; //每256个字节当一页,请注意不要写错页
uchar xdata *ncon; //用来处理写入或读入的缓存地址
uchar xdata len1; //rom第一段数据长度,看eprom.c
uchar xdata len2; //rom中间段数据页数,看eprom.c
uchar xdata len3; //rom末尾段数据长度,看eprom.c
如果不用外部存储器件,把关键字xdata去掉,然后再修改write_flash()
和read_flash()的声明部分参数
*/
//定义使用的ic,容量超过了这些ic就不能用了
#define d_24c01a 8 //定义ic每一页的字节数
#define d_24c02 8
#define d_24c04 16
#define d_24c08a 16
#define d_24c16a 16
#define numbyte_page d_24c16a
#define writedeviceaddress 0xa0 //写驱动地址指令
#define readdeviceaddress 0xa1 //读驱动地址指令
void nod2()
{unsigned char i; //4.6us延时
for (i=0;i《13;i++)
_nop_();
}
/*-------------------------------------------------------------
功能:发起始信号
------------------------------------------------------------*/
void start_cond()
{
sda = 1;
nod2();
scl = 1;
nod2();
sda = 0;
nod2();
scl = 0;
nod2();
}
/*-------------------------------------------------------------
功能:发停止信号
------------------------------------------------------------*/
void stop_cond()
{
sda = 0;
nod2();
scl = 1;
nod2();
sda = 1;
nod2();
scl = 0;
nod2();
}
/*-------------------------------------------------------------
功能:发确认信号
------------------------------------------------------------*/
void ack()
{
sda = 0;
nod2();
scl = 1;
nod2();
scl = 0;
nod2();
sda = 1;
nod2();
}
/*-------------------------------------------------------------
功能:发无确认信号
------------------------------------------------------------*/
void noack()
{
sda = 1;
nod2();
scl = 1;
nod2();
scl = 0;
nod2();
sda = 0;
nod2();
}
/*-------------------------------------------------------------
功能:读一个字节数据
------------------------------------------------------------*/
unsigned char read8bit()
{
unsigned char temp,rbyte=0;
for (temp = 0;temp《8;temp++)
{ sda=1;
nod2();
scl = 1;
nod2();
rbyte=(rbyte《《1)|sda;
scl = 0;
nod2();
}
return(rbyte);
}
/*-------------------------------------------------------------
功能:写一个字节数据
------------------------------------------------------------*/
write8bit(unsigned char input)
{
unsigned char i;
for (i=0;i《8;i++)
{ input 《《= 1;
sda = cy;
nod2();
scl = 1;
nod2();
scl = 0;
nod2();
sda = 0;
nod2();
}
f_rom=0; //chack
sda=1;
nod2();
nod2();
scl=1;
nod2();
nod2();
f_rom=sda;
scl=0;
nod2();
nod2();
}
/*------------------------------------------------------------
功能:从eeprom中给定一个地址连续读nlen个字节数据存放在以指针
ncontent开头的往下内容。
写地址为0x000~0x7ff,用参数page07代表最高位的页数(0~7)
------------------------------------------------------------*/
read_flash ( unsigned char xdata *ncontent, unsigned char naddr, unsigned int nlen ) large reentrant
{
unsigned char i,j;
//例如目标首地址为5,要写入20个字节,用24c02(每页8个字节)
//那么len1=8-5%8=3,第一页只能读3个字节
//len3=(20-3)%8=1,最后页只能读1个字节
//len2=(20-3-1)/8=2,中间能完整的读2页,刚好20个字节读完
//目标rom首地址离一页末要读的字节数
len1=numbyte_page-naddr%numbyte_page;
//目标rom最后页读入的字节数
len3=(nlen-len1)%numbyte_page;
//目标rom中间能够完整读入的页数
len2=(nlen-len1-len3)/numbyte_page;
if(len1》nlen) //假如读入长度不足把第一页写完,要更正参数
{ len1=nlen;
len2=0;
len3=0;
}
epromerr=0;
wrstart2:
epromerr++;
ncon=ncontent;
if(epromerr》200)
goto errdo2;
//===========================
//读第一段数据
//===========================
start_cond();
write8bit(writedeviceaddress+(page07《《1)); //写写控制字
if(f_rom==1)
goto wrstart2;
write8bit(naddr); //写地址
if(f_rom==1)
goto wrstart2;
start_cond();
write8bit(readdeviceaddress+(page07《《1)); //写读控制字
if(f_rom==1)
goto wrstart2;
if(len1》1) //读第一段数据
{ for(i=0;i《(len1-1);i++)
{ *ncon=read8bit();
ack();
ncon++;
}
}
*ncon=read8bit(); //读1个数
noack();
ncon++;
stop_cond(); //停止
nod2();
//===========================
//读中间段数据
//===========================
if(len2》0)
{ for(j=0;j《len2;j++)
{
epadd=naddr+(numbyte_page)*j+len1; //修正写入目标偏移地址
start_cond();
write8bit(writedeviceaddress+(page07《《1)); //写写控制字
if(f_rom==1)
goto wrstart2;
write8bit(epadd); //写地址
if(f_rom==1)
goto wrstart2;
start_cond();
write8bit(readdeviceaddress+(page07《《1)); //写读控制字
if(f_rom==1)
goto wrstart2;
for(i=0;i《(numbyte_page-1);i++) //读numbyte_page-1个字节
{ *ncon=read8bit();
ack();
ncon++;
}
*ncon=read8bit(); //读1个字节
noack();
ncon++;
stop_cond(); //停止
nod2();
}
}
//===========================
//读末尾段数据
//===========================
if(len3》0)
{ epadd=naddr+(numbyte_page)*len2+len1; //修正写入目标偏移地址
start_cond();
write8bit(writedeviceaddress+(page07《《1)); //写写控制字
if(f_rom==1)
goto wrstart2;
write8bit(epadd); //写地址
if(f_rom==1)
goto wrstart2;
start_cond();
write8bit(readdeviceaddress+(page07《《1)); //写读控制字
if(f_rom==1)
goto wrstart2;
if(len3》1) //读末尾段数据
{ for(i=0;i《(len3-1);i++)
{ *ncon=read8bit();
ack();
ncon++;
}
}
*ncon=read8bit(); //读1个数
noack();
ncon++;
stop_cond(); //停止
nod2();
}
/*
j=0;
restart: j++;
if (j==255)
goto errdo2;
start_cond(); //写开始信号
write8bit(writedeviceaddress); //写写控制字
if(f_rom==1) goto restart;
write8bit(naddr); //写地址
if(f_rom==1) goto restart;
start_cond(); //写开始信号
write8bit(readdeviceaddress); //写读控制字
if(f_rom==1) goto restart;
for(i=0;i《(nlen-1);i++) //读7个数
{ *ncontent=read8bit();
ack();
ncontent++;
}
*ncontent=read8bit(); //读1个数
noack();
stop_cond(); //停止
nod2();
*/
errdo2:;//////////////////////////////////////读数据超时处理
//outr:;
}
/*-------------------------------------------------------------
功能:从eeprom中给定一个地址naddr,连续写nlen个字节数据存放在以指针
ncontent开头的往下内容
写地址为0x000~0x7ff,用参数page07代表最高位的页数(0~7)
------------------------------------------------------------*/
write_flash ( unsigned char xdata *ncontent,unsigned char naddr, unsigned int nlen) large reentrant
{
//unsigned char epromerr; //用来统计写入出错的次数
unsigned char i,j; //for循坏用
//unsigned char xdata epadd; //用来作为rom目标地址,要进行计算
//unsigned char xdata len1; //rom第一段数据长度,看eprom.c
//unsigned char xdata len2; //rom中间段数据页数,看eprom.c
//unsigned char xdata len3; //rom末尾段数据长度,看eprom.c
//例如目标首地址为5,要写入20个字节,用24c02(每页8个字节)
//那么len1=8-5%8=3,第一页只能写3个字节
//len2=(20-3)%8=1,最后页只能写1个字节
//len3=(20-3-1)/8=2,中间能完整的写2页,刚好20个字节写完
//目标rom首地址离一页末要写的字节数
len1=numbyte_page-naddr%numbyte_page;
//目标rom最后页写入的字节数
len3=(nlen-len1)%numbyte_page;
//目标rom中间能够完整写入的页数
len2=(nlen-len1-len3)/numbyte_page;
if(len1》nlen) //假如写入长度不足把第一页写完,要更正参数
{ len1=nlen;
len2=0;
len3=0;
}
epromerr=0;
wrstart:
++epromerr;
ncon=ncontent; //重新修正缓存对应地址
if(epromerr》200)
goto errdo1;
//===========================
//写第一段数据
//===========================
start_cond();
write8bit(writedeviceaddress+(page07《《1)); //写写控制字
if(f_rom==1)
goto wrstart;
write8bit(naddr); //写地址
if(f_rom==1)
goto wrstart;
for(i=0;i《len1;i++) //写第一段数据
{ write8bit(*ncon);
if(f_rom==1)
goto wrstart;
ncon++;
}
stop_cond(); //首段写完
//===========================
//写中间的完整段数据
//===========================
if(len2》0)
{ for(j=0;j《len2;j++) //写len2页
{ epadd=naddr+(numbyte_page)*j+len1; //修正写入目标偏移地址
start_cond();
write8bit(writedeviceaddress+(page07《《1)); //写写控制字
if(f_rom==1)
goto wrstart;
write8bit(epadd); //写地址
if(f_rom==1)
goto wrstart;
for(i=0;i《numbyte_page;i++) //写完整的一页
{ write8bit(*ncon);
if(f_rom==1)
goto wrstart;
ncon++;
}
stop_cond(); //一段写完
}
}
//===========================
//写末尾段数据
//===========================
if(len3》0)
{ epadd=naddr+(numbyte_page)*len2+len1; //修正写入目标偏移地址
start_cond();
write8bit(writedeviceaddress+(page07《《1)); //写写控制字
if(f_rom==1)
goto wrstart;
write8bit(epadd); //写地址
if(f_rom==1)
goto wrstart;
for(i=0;i《len3;i++) //写末尾段数据
{ write8bit(*ncon);
if(f_rom==1)
goto wrstart;
ncon++;
}
stop_cond(); //末尾段写完
}
errdo1:;

汽车传动系简介(图)
Supermicro 庆祝 30 周年| 增长、创新、人工智能与绿色计算
RC和RL电路脉冲波不一样?
AT89C2051在多功能窗中的应用及电路图
工业相机相关专业技术问答
24c04读写程序详解
LVPECL与LVPECL之间是如何进行连接的?LVPECL到CML的连接?
电子芯闻早报:即将爆发的物联网产业
在电路设计中,DC/DC和LDO该如何选择
苹果13全部颜色有哪些
一种智能家居指纹识别门禁系统设计方案
频率测量的方法详解
ThinkCentreM910z一体机评测 诸多创新和人性化设计
华为P20 Plus曝光配徕卡三摄多出的摄像头有什么作用?
是德科技与英特尔携手完成负载均衡单节点2100万连接新建性能测试
还在使用指纹打卡?“无感考勤”你值得拥有
电子元器件在电路中有哪些作用
华为芯片为什么受制于美国
苹果和谷歌研究用于智能穿戴及家居产品的智能织物技术
LM3481可支持电压升压和动态负载
s