2013-06-04 10:24
满意回答 提问者采纳 2013-06-04 10:27
6位10进制数,转换为16进制,再写入EEPROM. long x;
分4个字节写入 uchar c1;
c1= x>>24; //最高字节 c1=x>>16; //次高字节 c1=x>>8; //次低字节 c1=x&0xff; //最低字节
分别写入就可以了。追问 我用的是stc12C5A60S2单片机,我将转化轩16进制的数保存在一个数组,然后整个数组写进去,当需要的时候再读出来还原成十进制数可否呢?回答 当然可以。追问 想了一下,不知应该如何用单片机C语言去实现啊,可以指导下不?提问者评价 谢谢哈评论 | ningling_21 知道达人 | 来自团队 单片机学习 | 十级 采纳率26%擅长: 其他编程语言 汇编语言 C/C++
16进制转换算成10进制程序
来源:本站整理 作者:佚名2009年01月14日 23:33 0 分享
[导读] 16进制转换算成10进制程序 unsigned char d[10]; //用于显示的10位显示缓存 //======================
关键词:进制
16进制转换算成10进制程序
unsigned char d[10]; //用于显示的10位显示缓存
//========================================================
//16进制to10进制输出子程序:显示数据,起始位,结束位,有无小数点 //========================================================
void output(unsigned long dd,unsigned char s,unsigned char e,unsigned char dip) { unsigned long div;
unsigned char tm[8],i,j; div=10000000;
for (i=0;i<8;i++) { tm[i]=dd/div; dd%=div; div/=10; }
for (i=0;i<6;i++) { if (tm[i]!=0) break; tm[i]=nul; }
tm[5]|=dip; //小数点控制,请看“串行LED数码管显示驱动程序” j=7;
for (i=s;i //把显示位5-9位的10进制数转换成为16进制数 unsigned int input(void) { unsigned int dd,dat; dd=10000;dat=0; for (i=5;i<10;i++) { dat+=dd*temp; dd/=10; } return(dat); } /* 89C51系列CPU编程器接收CPU程序*/ #i nclude unsigned int adds; // 13.8mS void int_t0(void) interrupt 1 { TH0=-100; b_break=1; } void wait(unsigned char w) { unsigned int t=w*184; b_break=0; TL0=-t%256-1;TH0=-t/256; while (b_break==0) {} } void nop(void) { _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); } unsigned char command(void) { TH0=-100;b_break=0; while (RI==0) {if (b_break==1) return(0);} RI=0; return(SBUF); } void earsure(unsigned char cpu) { switch (cpu) { case 1: //89C51 case 2:rst=p26=1;p27=p36=p37=0;nop();vpp=1;nop(); ale=0;wait(110);ale=1;nop(); break; case 3: case 4:break; case 5: case 6:break; } } void program(unsigned char cpu) { unsigned int bdata adds=0; unsigned char d; switch (cpu) { case 1: //89C51 case 2: p36=p37=1;rst=1; while (1) { TH0=-100;b_break=0; while (RI==0) {if (b_break==1) return;} RI=0; d=SBUF; //address P0=adds%256; P2=adds/256; p27=1; //data P1=d; nop(); //48clcl //vpp vpp=1; nop(); //48clcl //ale ale=0; wait(1);//100uS ale=1; nop(); //10uS vpp=0; nop(); //48clcl p27=0; nop(); //48clcl P1=0xff; TH0=-100;b_break=0; while (d!=P1) {if (b_break==1) return;} polling SBUF=d; adds++; } break; case 3: case 4: case 5: case 6:break; } } void lock(unsigned char cpu) { unsigned char i; switch (cpu) { case 1: //89c51 case 2: //lock 1 rst=p26=p36=p27=p37=1;nop(); vpp=1; nop(); ale=0; //data // for (i=0;i<6;i++) wait(100); wait(1); ale=1; nop(); vpp=0; nop(); //lock 2 rst=p26=p27=1;p36=p37=0;nop(); vpp=1; nop(); ale=0; // for (i=0;i<6;i++) wait(100); wait(1); ale=1; nop(); vpp=0; nop(); //lock 3 rst=p26=p36=1;p27=p37=0;nop(); vpp=1; nop(); ale=0; // for (i=0;i<6;i++) wait(100); wait(1); ale=1; nop(); vpp=0; nop(); break; case 3: case 4: case 5: case 6:break; } } void main(void) { unsigned char disp,flash,temp,cpu; EA=1; SCON=0xd8;PCON=0x80; TMOD=0x21; TL1=TH1=0xff;TR1=1; TH0=-100;ET0=TR0=1; flash=0x80; while (1) { temp=command(); switch (temp) { case 0: case 1: //89c51 case 2: //89C52 case 3: //80f51 case 4: //80F52 case 5: //87F51 case 6:cpu=temp;SBUF=temp;break;//87f52 case e:SBUF=temp;earsure(cpu);break; //erasure case p:SBUF=temp;program(cpu);break; //program case l:lock(cpu);SBUF=temp;break; //lock default:SBUF=temp;break; } b_break=0; if ((++disp)>flash) {disp=0;led=!led;} } } //HT1380实时时钟驱动程序 sbit clock_dat=P0^1; sbit clock_clk=P0^2; sbit clock_rst=P0^3; sbit a0=ACC^0; sbit a1=ACC^1; sbit a2=ACC^2; sbit a3=ACC^3; sbit a4=ACC^4; sbit a5=ACC^5; sbit a6=ACC^6; sbit a7=ACC^7; void clock_out(unsigned char dd) { ACC=dd; clock_dat=a0;clock_clk=1;clock_clk=0; clock_dat=a1;clock_clk=1;clock_clk=0; clock_dat=a2;clock_clk=1;clock_clk=0; clock_dat=a3;clock_clk=1;clock_clk=0; clock_dat=a4;clock_clk=1;clock_clk=0; clock_dat=a5;clock_clk=1;clock_clk=0; clock_dat=a6;clock_clk=1;clock_clk=0; clock_dat=a7;clock_clk=1;clock_clk=0; } unsigned char clock_in(void) { clock_dat=1; a0=clock_dat; clock_clk=1;clock_clk=0;a1=clock_dat; clock_clk=1;clock_clk=0;a2=clock_dat; clock_clk=1;clock_clk=0;a3=clock_dat; clock_clk=1;clock_clk=0;a4=clock_dat; clock_clk=1;clock_clk=0;a5=clock_dat; clock_clk=1;clock_clk=0;a6=clock_dat; clock_clk=1;clock_clk=0;a7=clock_dat; return(ACC); } unsigned char read_clock(unsigned char ord) { unsigned char dd=0; clock_clk=0; clock_rst=0; clock_rst=1; clock_out(ord); dd=clock_in(); clock_rst=0; clock_clk=1; return(dd); } void write_clock(unsigned char ord,unsigned char dd) { clock_clk=0; clock_rst=0; clock_rst=1; clock_out(ord); clock_out(dd); clock_rst=0; clock_clk=1; } /*单个汉字库字摸提取程序,tc2.0编译*/ #i nclude \"stdio.h\" #i nclude \"dos.h\" #i nclude \"process.h\" #i nclude \"string.h\" void main(void) { long int num_bytes,qm,wm; unsigned char d,i,j,k,a[132],b[132]; unsigned char * data; unsigned char * hz; static unsigned char dd[103]; FILE *fp; if ((fp=fopen(\"hzk16f\ printf(\"can't open hzk16\\n\"); exit(1); } clrscr(); while (1) { data=(unsigned char *) malloc(33); printf(\"please input:\\n\"); scanf(\"%s\/*输入一个汉字*/ qm=* dd; /*通过区位码计算其在hzk16f文件中的偏移地址*/ qm=qm-161; if (qm>87) exit(0); wm=* (dd+1); wm=wm-161; if (wm>94) exit(0); num_bytes=((long)qm*94+wm)*32; fseek(fp,num_bytes,SEEK_SET); fgets(data,33,fp); for (i=0;i<32;i++) b[i]=* data++; for (i=0;i<32;i+=2) a[i/2]=b[i]; for (i=0;i<32;i+=2) a[i/2+16]=b[i+1]; for (i=8;i<16;i++) b[i]=a[i]; for (i=8;i<16;i++) a[i]=a[i+8]; for (i=8;i<16;i++) a[i+8]=b[i]; /*转换,hzf16f在电脑的储存格式是以行为字节计算的,一般的lcd都采用以列为字节计算*/ for (k=0;k<32;k+=8) { for (j=0;j<8;j++) { d=0; for (i=0;i<8;i++) { if (a[i+k]>=0x80) { switch (i) { case 0:d+=1;break; case 1:d+=2;break; case 2:d+=4;break; case 3:d+=8;break; case 4:d+=0x10;break; case 5:d+=0x20;break; case 6:d+=0x40;break; case 7:d+=0x80;break; } } } for (i=0;i<8;i++) a[i+k]<<=1; b[j+k]=d; } } clrscr(); printf(\"/*%s:*/\\n\/*输出0x00格式的16进制数*/ for (k=0;k<32;k+=8) { for (j=0;j<8;j++) printf(\"0x%x,\ printf(\"\\n\"); } getch(); } } //按键扫描驱动程序 unsigned char key,key_h,kpush; unsigned int key_l; //按键连接到p1.0、p1.1、p1.2 void int_t0(void) interrupt 1 { unsigned char dd,i; TL0=TL0+30;TH0=0xfb; //800 /* 按键判别 */ if ((P1&0x7)==0x7) { if ((key_l>30)&&(key_l<800)&&(key_h>30)) { //释放按键,如果之前按键时间少于1秒,读入键值 key=kpush; } if ((++key_h)>200) key_h=200; key_l=0; if (key>=0x80) key=0; //如果之前的按键为长按1秒,清除键值 } else { kpush=P1&0x7; key_l++; if ((key_l>800)&&(key_h>30)) { //如果按键超过1秒,键值加0x80标志长按键 key=kpush|0x80; key_h=0; key_l=0; } } } void main(void) { TMOD=0x1;TR0=1;ET0=1;EA=1; while (1) { while (!key) {} switch (key) { case 1:break; case 2:break; } } //串行驱动led显示, //一个74hc595位移寄存器驱动三极管驱动led位, //两个74hc595驱动led段,方式位5位x8段x2=10个数码管 //5分频,每次扫描时间位1.25ms //定义特殊符号 #define nul 0xf #define qc 0xc #define qb 0xb #define q_ 0xa #define q__ 0xd #define q___ 0xe #define qp 0x10 #define qe 0x11 #define qj 0x12 #define qn 0x13 #define qf 0x14 #define qa 0x15 #define qr 0x16 #define qd 0x17 #define qu 0x18 #define ql 0x19 #define qh 0x1a #define qwen 0x1b #define qt 0x1c #define qla 0x1d #define qlb 0x1e #define qlc 0x1f #define qld 0x20 #define qle 0x21 #define qlf 0x22 #define qlg 0x23 #define qldp 0x24 //显示段信息,不同led排列组合的段信息只需更改8个数值即可。 //因此,该定义具有通用性。 // 显示 // -d 20 // |c 40 |e 10 // - g 80 // |b 2 |f 4 // _a1 .dp 8 #define pa 1 #define pb 2 #define pc 0x40 #define pd 0x20 #define pe 0x10 #define pf 4 #define pg 0x80 #define pdp 8 //-------------- #define l0 pdp+pg #define l1 255-pf-pe #define l2 pdp+pc+pf #define l3 pdp+pc+pb #define l4 pdp+pa+pb+pd #define l5 pdp+pb+pe #define l6 pdp+pe #define l7 pdp+pc+pg+pb+pa #define l8 pdp #define l9 pdp+pb #define la pdp+pa #define lb pdp+pd+pe #define lc pdp+pg+pe+pf #define ld pdp+pc+pd #define le pdp+pe+pf #define lf pdp+pe+pf+pa #define l_ 255-pg #define lnul 255 #define ll pdp+pg+pd+pf+pe #define lp pdp+pa+pf #define lt pdp+pd+pe+pf #define lr pdp+pe+pf+pg+pa #define ln pdp+pg+pa #define lh pdp+pd+pe+pa #define ly pdp+pb+pd #define lu pdp+pg+pd #define l__ pdp+pg+pb+pc+pe+pf #define l___ l__-pg #define l_1 255-pa #define l_2 255-pa-pg #define lj 255-(pe+pf+pa) #define lwen 255-(pd+pe+pg+pb) #define lall 0 #define lla 255-pa #define llb 255-pb #define llc 255-pc #define lld 255-pd #define lle 255-pe #define llf 255-pf #define llg 255-pg #define lldp 255-pdp //串行送出的位信息,目前是10位led显示。 unsigned char code un_dig[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb}; //串行送出的短信息。 unsigned char code un_disp[]={l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l_,lb,lc,l__,l___,lnul,lp,le,lj,ln,lf,la,lr,ld,lu, ll,lh,lwen,lt,lla,llb,llc,lld,lle,llf,llg,lldp,lnul}; sbit d_clk=P0^0; //移位时钟 sbit d_dat=P0^1; //移位数据 sbit d_st=P0^2; //移位锁定 unsigned char dig; //位扫描计数器 unsigned char d[10]; //显示缓冲 //送出8位串行数据 void out_disp(unsigned char dd) { unsigned char i; for (i=0;i<8;i++) { if (dd&1) d_dat=1; else d_dat=0; d_clk=0; dd>>=1; d_clk=1; } } //控制小数点和闪烁,显示数据|0x040表示有小数点;显示数据|0x80表示闪烁。 void out_displ(unsigned char dd) { if (dd>=0x80) { if (s001>flash_time) {out_disp(0xff);return;} } dd&=0x7f; if (dd>=0x40) { dd=un_disp[dd&0x3f]^pdp; } else dd=un_disp[dd]; out_disp(dd); } unsigned int s001; //闪烁时间参考 void int_t0(void) interrupt 1 { unsigned char dd; TL0=TL0+30;TH0=0xfb; //800 time++; if ((++s001)>=800) s001=0; // 显示 if ((++dig)>4) dig=0; d_st=0; dd=d[dig+5]; out_displ(dd); dd=d[dig]; out_displ(dd); out_disp(un_dig[dig]); d_st=1; } void main(void) { unsigned char i; TMOD=0x1; TR0=ET0=1; EA=1; for (i=0;i<10;i++) d[i]=i; //display test while (1) {} } STC 单片机中的eeprom写入和读取6位的10进制数需要进行数据类型转换吗?具体是怎样现的呢? 2013-06-04 10:24 dwsxfg | 分类:内存 | 浏览34次 分享到: 检举|2013-06-04 10:27 提问者采纳 6位10进制数,转换为16进制,再写入EEPROM. long x; 分4个字节写入 uchar c1; c1= x>>24; //最高字节 c1=x>>16; //次高字节 c1=x>>8; //次低字节 c1=x&0xff; //最低字节 分别写入就可以了。 追问 我用的是stc12C5A60S2单片机,我将转化轩16进制的数保存在一个数组,然后整个数组写进去,当需要的时候再读出来还原成十进制数可否呢? 回答 当然可以。 追问 想了一下,不知应该如何用单片机C语言去实现啊,可以指导下不? 提问者评价 谢谢哈 一个牛人的关于STC的EEPROM的介绍(很不错) ***说明:相关内容来自网上,整理而成。转贴在此主要供参考学习用 单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无 法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等 存储器来实现。在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通 过IIC 或SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开发上也要花 更多的心思。在STC 单片机中内置了EEPROM(其实是采用IAP 技术读写内部FLASH 来 实现EEPROM),这样就节省了片外资源,使用起来也更加方便。下面就详细介绍STC 单 片机内置EEPROM 及其使用方法。 STC 各型号单片机内置的EEPROM 的容量各有不同,见下表: (内部EEPROM 可以擦写100000 次以上) 上面提到了IAP,它的意思是“在应用编程”,即在程序运行时程序存储器可由程序自 身进行擦写。正是是因为有了IAP,从而可以使单片机可以将数据写入到程序存储器中,使 得数据如同烧入的程序一样,掉电不丢失。当然写入数据的区域与程序存储区要分开来,以 使程序不会遭到破坏。 要使用IAP 功能,与以下几个特殊功能寄存器相关: ISP_DATA: ISP/IAP 操作时的数据寄存器。 ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处 ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。 ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。 ISP_CMD: ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。 ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。 当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG 先写入0x46,再写入0xb9,ISP/IAP 命令才会生效。 单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节) STC89C51RC,STC89LE51RC 0x2000 共八个扇区 STC89C52RC,STC89LE52RC 0x2000 共八个扇区 STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区 STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区 STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区 寄存器标识地址名称7 6 5 4 3 2 1 0 初始值 ISP_DATA 0xE2 ISP/IAP闪存数据寄存器11111111 ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000 ISP_ADDRL 0xE4 ISP/IAP 闪存地址低位00000000 ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2 MS1 MS0 xxxxx000 ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxx ISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST WT2 WT1 WT0 00xx000 B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式选择 保留命令选择 - - - - - 0 0 0 待机模式,无ISP/IAP 操作 - - - - - 0 0 1 对用户的应用程序Flash 区及数据Flash 区字节读 - - - - - 0 1 0 对用户的应用程序Flash 区及数据Flash 区字节编程 - - - - - 0 1 1 对用户的应用程序Flash 区及数据Flash 区扇区擦除 ISP_CONTR:ISP/IAP 控制寄存器。 ISPEN:ISP/IAP 功能允许位。0:禁止ISP/IAP 编程改变Flash,1:允许编程改变Flash SWBS:软件选择从用户主程序区启动(0),还是从ISP 程序区启动(1)。 SWRST:0:不操作,1:产生软件系统复位,硬件自动清零。 ISP_CONTR 中的SWBS 与SWRST 这两个功能位,可以实现单片机的软件启动,并 启动到ISP 区或用户程序区,这在“STC 单片机自动下载”一节,亦有所应用。 如: ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP 程序区开始运行 程序。 ISP_CONTR=0x20? 则可以实现从ISP 程序区软件复位到用户应用程序区开始运行 程序。 用IAP 向Flash 中读写数据,是需要一定的读写时间的,读写数据命令发出后,要等待 一段时间才可以读写成功。这个等待时间就是由WT2、WT1、WT0 与晶体振荡器频率决定 的。 (以上的建议时钟是(WT2、WT1、WT0)取不同的值时的标称时钟,用户系统中的时钟 不要过高,否则可能使操作不稳定。) stc单片机EEPROM读写(一) EEPROM 操作函数: #define RdCommand 0x01 #define PrgCommand 0x02 #define EraseCommand 0x03 #define Error 1 #define Ok 0 #define WaitTime 0x01 #define PerSector 512 unsigned char xdata Ttotal[512]? /* 打开ISP,IAP 功能 */ void ISP_IAP_enable(void) D7 D6 D5 D4 D3 D2 D1 D0 ISPEN SWBS SWRST - - WT2 WT1 WT0 设置等待时间CPU 等待时间(机器周期) WT2 WT1 WT0 读取编程扇区擦除建议的系统时钟 0 1 1 6 30 5471 5MHz 0 1 0 11 60 10942 10MHz 0 0 1 22 120 21885 20MHz 0 0 0 43 240 43769 40MHz { EA=0?/* 关中断*/ ISP_CONTR|=0x18?/*0001,1000*/ ISP_CONTR|=WaitTime?/*写入硬件延时*/ ISP_CONTR|=0x80?/*ISPEN=1*/ } /* 关闭ISP,IAP 功能 */ void ISP_IAP_disable(void) { ISP_CONTR&=0x7f?/* ISPEN = 0 */ ISP_TRIG=0x00? EA=1?/* 开中断*/ } /* 公用的触发代码 */ void ISPgoon(void) { ISP_IAP_enable()?/* 打开ISP,IAP 功能*/ ISP_TRIG=0x46?/* 触发ISP_IAP 命令字节1 */ ISP_TRIG=0xb9?/* 触发ISP_IAP 命令字节2 */ _nop_()? } /* 字节读 */ unsigned char byte_read(unsigned int byte_addr) { ISP_ADDRH=(unsigned char)(byte_addr>>8)? /* 地址赋值*/ ISP_ADDRL=(unsigned char)(byte_addr&0x00ff)? ISP_CMD&=0xf8? /* 清除低3 位*/ ISP_CMD|=RdCommand?/* 写入读命令*/ ISPgoon()?/* 触发执行*/ ISP_IAP_disable()?/* 关闭ISP,IAP 功能*/ return ISP_DATA?/* 返回读到的数据*/ } /* 扇区擦除 */ void sectorerase(unsigned int sector_addr) { unsigned int iSectorAddr? iSectorAddr=(sector_addr&0xfe00)?/* 取扇区地址*/ ISP_ADDRH=(unsigned char)(iSectorAddr>>8)? ISP_ADDRL=0x00? ISP_CMD&=0xf8?/* 清空低3 位*/ ISP_CMD|=EraseCommand?/* 擦除命令3*/ ISPgoon()?/* 触发执行*/ ISP_IAP_disable()?/* 关闭ISP,IAP 功能*/ } /* 字节写 */ void byte_write(unsigned int byte_addr, unsigned char original_data) { ISP_ADDRH=(unsigned char)(byte_addr>>8)? /* 取地址*/ ISP_ADDRL=(unsigned char)(byte_addr & 0x00ff)? ISP_CMD&=0xf8?/* 清低3 位*/ ISP_CMD|=PrgCommand?/* 写命令2*/ ISP_DATA=original_data?/* 写入数据准备*/ ISPgoon()?/* 触发执行*/ ISP_IAP_disable()?/* 关闭IAP 功能*/ } /* 字节写并校验 */ unsigned char byte_write_verify(unsigned int byte_addr, unsigned char original_data) { ISP_ADDRH=(unsigned char)(byte_addr>>8)? /* 取地址*/ ISP_ADDRL=(unsigned char)(byte_addr&0xff)? ISP_CMD&=0xf8?/* 清低3 位*/ ISP_CMD|=PrgCommand?/* 写命令2*/ ISP_DATA=original_data? ISPgoon()?/* 触发执行*/ /* 开始读,没有在此重复给地址,地址不会被自动改变*/ ISP_DATA=0x00?/* 清数据传递寄存器*/ ISP_CMD&=0xf8?/* 清低3 位*/ ISP_CMD|=RdCommand?/* 读命令1*/ ISP_TRIG=0x46?/* 触发ISP_IAP 命令字节1 */ ISP_TRIG=0xb9?/* 触发ISP_IAP 命令字节2 */ _nop_()?/* 延时*/ ISP_IAP_disable()?/* 关闭IAP 功能*/ if(ISP_DATA==original_data)/* 读写数据校验*/ return Ok?/* 返回校验结果*/ else return Error? } /* 数组写入 */ unsigned char arraywrite(unsigned int begin_addr, unsigned int len, unsigned char *array) { unsigned int i? unsigned int in_addr? /* 判是否是有效范围,此函数不允许跨扇区操作*/ if(len > PerSector) return Error? in_addr = begin_addr & 0x01ff?/* 扇区内偏移量*/ if((in_addr+len)>PerSector) return Error? in_addr = begin_addr? /* 逐个写入并校对*/ ISP_IAP_enable()?/* 打开IAP 功能*/ for(i=0?i ISP_ADDRH=(unsigned char)(in_addr >> 8)? ISP_ADDRL=(unsigned char)(in_addr & 0x00ff)? ISP_DATA=array[i]? /* 取数据*/ ISP_CMD&=0xf8?/* 清低3 位*/ ISP_CMD|=PrgCommand?/* 写命令2 */ ISP_TRIG=0x46?/* 触发ISP_IAP 命令字节1 */ ISP_TRIG=0xb9?/* 触发ISP_IAP 命令字节2 */ _nop_()? /* 读回来*/ ISP_DATA=0x00? ISP_CMD&=0xf8?/* 清低3 位*/ ISP_CMD|=RdCommand?/* 读命令1*/ ISP_TRIG=0x46?/* 触发ISP_IAP 命令字节1 */ ISP_TRIG=0xb9?/* 触发ISP_IAP 命令字节2 */ _nop_()? /* 比较对错*/ if(ISP_DATA!=array[i]) { ISP_IAP_disable()? return Error? } in_addr++?/* 指向下一个字节*/ } ISP_IAP_disable()? return Ok? } /* 扇区读出 */ /* 程序对地址没有作有效性判断,请调用前事先保证他在规定范围内*/ void arrayread(unsigned int begin_addr, unsigned char len) { unsigned int iSectorAddr? unsigned int i? iSectorAddr = begin_addr? // & 0xfe00? /* 取扇区地址*/ ISP_IAP_enable()? for(i=0?i ISP_ADDRL=(unsigned char)(iSectorAddr & 0x00ff)? ISP_CMD&=0xf8?/* 清低3 位*/ ISP_CMD|=RdCommand?/* 读命令1*/ ISP_DATA=0? ISP_TRIG=0x46?/* 触发ISP_IAP 命令字节1 */ ISP_TRIG=0xb9?/* 触发ISP_IAP 命令字节2 */ _nop_()? Ttotal[i]=ISP_DATA? iSectorAddr++? } ISP_IAP_disable()?/* 关闭IAP 功能*/ } 主函数对EEPROM 操作函数进行调用: #include #include void delay(unsigned int time) { while(time) ? } void main() { _ADOS(22.1184)? //ADOS 自动下载 //for(i=0?i<100?i++) //{ //Ttotal[i]=i? //} //arraywrite(0x8000,100,Ttotal)? /* 第一次运行时向EEPROM 中写入数据 然后再将写入函数注释掉,将先前写 入的数据读出,输出在P2 口上。 */ arrayread(0x8000,100)? for(i=0?i<100?i++) { P2=~Ttotal[i]? delay(10000)? } while(1)? } stc单片机EEPROM读写(二) sfr isp_data=0xe2; sfr isp_addrh=0xe3; sfr isp_addrl=0xe4; sfr isp_cmd=0xe5; sfr isp_trig=0xe6; sfr isp_contr=0xe7; unsigned char eeprom_read(unsigned int addres); void eeprom_write(unsigned int address,unsigned char wdata); void eeprom_eares(unsigned int addres);//扇区擦除。 void eeprom_eares(unsigned int addres)//扇区擦除。 {unsigned i; isp_addrl=addres; //低位地址 isp_addrh=addres>>8; //高位地址 isp_contr=0x01; isp_contr=isp_contr|0x80; //设时间与充ISP操作。 isp_cmd=0x03; //扇区命命令 isp_trig=0x46; //触发 isp_trig=0xb9; //触发启动。 for(i=0;i<3;i++); isp_addrl=0xff; isp_addrh=0xff; isp_contr=0x00; isp_cmd=0x00; isp_trig=0x00; } void eeprom_write(unsigned int addres,unsigned char write_data)//写数据。 {unsigned char i; isp_data=write_data; //要写入的数据。 isp_addrl=addres; //低位地址 isp_addrh=addres>>8; //高位地址 isp_contr=0x01; isp_contr=isp_contr|0x80; //设时间与充ISP操作。 isp_cmd=0x02; //写命令 isp_trig=0x46; //触发 isp_trig=0xb9; //触发启动。 for(i=0;i<3;i++); isp_addrl=0xff; isp_addrh=0xff; isp_contr=0x00; isp_cmd=0x00; isp_trig=0x00; } unsigned char eeprom_read(unsigned int addres) {unsigned char i,z; isp_addrl=addres; //低位地址 isp_addrh=addres>>8; //高位地址 isp_contr=0x01; isp_contr=isp_contr|0x80; //设时间与充ISP操作。 isp_cmd=0x01; //写命令 isp_trig=0x46; //触发 isp_trig=0xb9; //触发启动。 for(i=0;i<3;i++); isp_addrl=0xff; isp_addrh=0xff; isp_contr=0x00; isp_cmd=0x00; isp_trig=0x00; z=\"isp\"_data; return(z); } stc单片机EEPROM读写(三) ;;; 内部EEPROM读写定义 ISP_DATA EQU 0E2H ;写入读出数据寄存器. ISP_ADDRH EQU 0E3H ;地址寄存器高8位 ISP_ADDRL EQU 0E4H ;地址寄存器低8位 ISP_CMD EQU 0E5H ;命令模式寄存器 ISP_TRIG EQU 0E6H ;命令触发寄存器 ISP_CONTR EQU 0E7H ;ISP/IAP控制寄存器. ISP_IAP_BYTE_READ EQU 1 ;字节读 ISP_IAP_BYTE_PROGRAM EQU 2 ;字节编程,要空才能写 ISP_IAP_SECTOR_ERASE EQU 3 ;扇区擦除, WAIT_TIME EQU 1 ;20M以下为1 BYTE_ADDR_HIGH EQU 60H ;高位地址 BYTE_ADDR_LOW EQU 61H ;低位地址 BYTE_WRITE_DATA EQU 62H ;要写入的数据 ;***********************内部EEPROM操作************************* READ_EEPROM:MOV ISP_ADDRH,ISP_ADDRH ;送高地址 MOV ISP_ADDRL,ISP_ADDRL ;送低地址 MOV ISP_CONTR,#01h ;设置等等待时间 ORL ISP_CONTR,#80h ;允许ISP/IAP操作 MOV ISP_CMD,#01h ;送读命令 MOV ISP_TRIG,#46H ;触发 MOV ISP_TRIG,#0B9H ;触发启动. NOP NOP MOV ISP_CONTR,#00H MOV ISP_CMD,#00H MOV ISP_TRIG,#00H MOV ISP_ADDRH,#0FFH MOV ISP_ADDRL,#0FFH MOV 6AH,ISP_DATA ;读出的数据放到6AH单元中。 RET WRITE_EARES: MOV WDT,#34H CLR EA ;关中断 MOV ISP_ADDRH,ISP_ADDRH ;送高地址 MOV ISP_ADDRL,ISP_ADDRL ;送低地址 MOV ISP_CONTR,#1h ;设置等等待时间 ORL ISP_CONTR,#10000000B ;允许ISP/IAP操作 MOV ISP_CMD,#3h ;送扇区命令 MOV ISP_TRIG,#46H ;触发 MOV ISP_TRIG,#0B9H ;触发启动. NOP NOP MOV ISP_CONTR,#00H MOV ISP_CMD,#00H MOV ISP_TRIG,#00H MOV ISP_ADDRH,#0FFH MOV ISP_ADDRL,#0FFH SETB EA RET WRITE_EEPROM:MOV WDT,#34H CLR EA MOV ISP_DATA,BYTE_WRITE_DATA ;要写入的数据 MOV ISP_ADDRH,ISP_ADDRH ;送高地址 MOV ISP_ADDRL,ISP_ADDRL ;送低地址 MOV ISP_CONTR,#1h ;设置等等待时间 ORL ISP_CONTR,#10000000B ;允许ISP/IAP操作 MOV ISP_CMD,#02h ;送写命令 MOV ISP_TRIG,#46H ;触发 MOV ISP_TRIG,#0B9H ;触发启动. NOP NOP MOV ISP_CONTR,#00H MOV ISP_CMD,#00H MOV ISP_TRIG,#00H MOV ISP_ADDRH,#0FFH MOV ISP_ADDRL,#0FFH SETB EA ;开中断 RET STC内部EEPROM怎么存入多组数据 用“ 数组 ”或者“ 结构体 ” 【 数组 】例如: uint8 BUF; uint8 N; EROM_C( 1 ); //擦除扇区1(0x0200 ~ 0x02FF) EROM_W_8( 0x0230, BUF, 100 ); //将数组BUF依次写入EEPROM从0x0230开始的连续100个单元 EROM_R_8( 0x0230, BUF, 100 ); //读出EEPROM从0x0230开始的连续100个单元写入数组BUF EROM_R_8( 0x0290, N, 10 ); //读出EEPROM从0x0290开始的连续10个单元写入数组N 【 结构体 】例如: struct STR_1 { uint8 sec; uint8 min; uint8 hour; uint8 day; uint8 month; uint8 week; uint8 year; } data NOW; EROM_C( 0 ); //擦除扇区0(0x0000 ~ 0x01FF) EROM_W_8( 0x0000, &NOW.sec, 7 ); //将结构体中的秒、分、时、日、月、星期、年这7个数据依次写入EEPROM从0x0000开始的连续7个单元 EROM_R_8( 0x0000, &NOW.sec, 7 ); //读出EEPROM从0x0000开始的连续7个单元写入结构体 具体程序:STC通用EEPROM操作函数(通杀1T、12T系列所有型号,支持连续读/写) 因篇幅问题不能全部显示,请点此查看更多更全内容