单片机掉电保存数据电路,程序
自学的,电路图不会画,随便看看
电源上电先给外围设备供电,然后通过二极管给电容C1充电,给单片机供电,
电源有电时,中断IO口为高电平,电源掉电触发IO口下降沿中断,执行eeprom保存数据,同时电容代替电源单独给单片机供电220uF存几个字节没问题,存多要加大电容
程序里有个问题搞不明白,求各路大神解惑!
中断程序里调用子程序有时候无法赋值给子程序,不知道什么原因,子程序换名字重写一份了的,不存在重复调用问题。
Write_EEP2(sto1602+num1,0);这个可以正常把值赋给子程序
void Write_EEP2(uint addr,uchar dat) //地址addr,写入dat
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_DATA=dat;
IAP_CMD=2;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
}
Read_EEP2(sto1602+num1);这个就不行,我在子程序里读取addr显示在数码管上,数值是4,5之类的,正常应该是1024以上
void Read_EEP2(uint addr) //地址addr读取数据
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_CMD=1;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
}
#include<reg51.h>
//#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sfr P5=0xc8; //声明P5端口地址
sfr P2M0=0x96; //声明P2引脚模式寄存器
sfr P3M0=0xb2; //声明P3引脚模式寄存器
sfr P3M1=0XB1; //声明P3引脚模式寄存器
sfr AUXR=0x8e; //声明辅助寄存器
sfr INT_CLKO=0X8F; //外部中断与时钟输出控制寄存器
sfr ADC_RES=0xBD; //声明转换结果寄存器
sfr ADC_RESL=0xBE; //声明转换结果寄存器低2位
sfr P1ASF=0x9D; //声明P1口模拟功能寄存器 模拟功能开关
sfr ADC_CONTR=0xBC;//声明数模转换寄存器
sfr T2H=0xd6; //声明定时器2寄存器
sfr T2L=0xd7;
sfr IAP_CONTR=0xc7; //定义IAP控制寄存器
//IAPEN(B7)置1时 允许操作eeprom
//CMD_FAIL(B4)错误时系统置1,需软件清零
//WT2 WT1 WT0系统等待设置 ≥12mhz011
sfr IAP_DATA=0XC2; //ISP/IAP数据寄存器 EEPROM缓存空间
sfr IAP_ADDRH=0XC3; //地址高8位
sfr IAP_ADDRL=0XC4; //地址低8位
sfr IAP_CMD=0XC5; //ISP命令寄存器 01读 10写 11擦除
sfr IAP_TRIG=0XC6; //ISP命令触发寄存器 先写0x5a 再写0xa5触发
sbit DA=P2^4; //数码管位选
sbit DB=P3^2;
sbit DC=P3^6;
sbit DD=P2^0;
sbit DE=P2^1;
sbit DF=P2^3;
sbit DG=P3^5;
sbit DP=P3^7;
sbit B1=P2^5; //数码管段选
sbit B2=P2^2;
sbit B3=P3^3;
sbit B4=P3^4;
sbit SCK=P2^7; //串行时钟输出到max6675
sbit CS=P1^0; //片选端,CS为低时启动串行接口
sbit SO=P1^1; //串行数据输入到单片机
sbit keyx1=P2^6; //定义键盘键位
sbit keyx2=P2^7;
sbit keyx3=P1^0;
sbit keyx4=P1^1;
sbit keyy1=P1^2;
sbit keyy2=P1^3;
sbit keyy3=P1^4;
sbit keyy4=P1^5;
sbit keyy5=P1^6;
sbit S1=P5^4; //定义pwm信号接口
sbit SCK1602=P1^4;
sbit RCK1602=P1^5;
sbit SI1602=P1^6;
bit busy,pwmflag;
uchar count,count2,Flag_temp,Flag_key,keynow,keyold,mode,key; //定义计数,热电偶就绪
uint temp,value,t0; //定义温度,按键值,定时器0计数
uchar code duan[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0xcf}; //定义常量数组数码管段选 code 0-15 p.
uchar code wei[]={0xf7,0xfb,0xfd,0xfe}; //数码管位选
////////1602时钟///////
uchar code zi1602[]=
{
0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00, //℃ 0x00
0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x00, //年 0x01
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00, //月 0x02
0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00, //日 0x03
};
uchar mon,week,day,hour,min,sec,set;
uint num,year=2018,sto1602=0x0400; //第三扇区
uchar x,OP1,OP2,DOP2; //定义运算符 + - * / = c
uint tOP2,value1,value2;
long uint adc; //定义长整数,不然出错
void disduan(uchar dd)
{
DA=dd>>7;DB=dd>>6&1;DC=dd>>5&1;DD=dd>>4&1;DE=dd>>3&1;DF=dd>>2&1;DG=dd>>1&1;DP=dd&1;
}
void diswei(uchar dw)
{
B1=dw>>3&1;B2=dw>>2&1;B3=dw>>1&1;B4=dw&1;
}
void delay(uint n) //@12.000MHz
{
uchar ii, j;
while(n--)
{
ii = 12;
j = 169;
do
{
while (--j);
} while (--ii);
}
}
void Send1602(uchar dat1) //hgfedcba rs rw e d4 d5 d6 d7 空
{
uchar i;
for(i=7;i>4;i--) //发送7-5
{
SI1602=dat1>>i&1;
SCK1602=0;
SCK1602=1; //上升沿移入数据
}
for(i=1;i<5;i++) //发送1-4
{
SI1602=dat1>>i&1;
SCK1602=0;
SCK1602=1; //上升沿移入数据
}
SI1602=dat1&1; //发送0
SCK1602=0;
SCK1602=1;
RCK1602=0;
RCK1602=1; //上升沿输出数据
}
void dis1602(uchar a,uchar b) //a为0发送指令,为1发送数据 7654 3210
{
a<<=7;
Send1602(b>>3&0x1e|a); //1001 1110 高4位
delay(2);
Send1602(b>>3&0x1e|0x20|a); //1011 1110 e使能信号
delay(2);
Send1602(b>>3&0x1e|a); //1001 1110 高4位
delay(10);
Send1602(b<<1&0x1e|a); //1001 1110 低4位
delay(2);
Send1602(b<<1&0x1e|0x20|a); //1011 1110 e使能信号1011 0100
delay(2);
Send1602(b<<1&0x1e|a); //1001 1110 低4位
delay(10);
}
void print1602(uchar a1,uchar *b1)
{
dis1602(0,a1+0x80); //定位光标地址
while(*b1!='\0')
{
dis1602(1,*b1++);
}
*b1=0;
}
void init1602()
{
uchar i1;
delay(15);
dis1602(0,0x33);
dis1602(0,0x32);
dis1602(0,0x28); //4位总线模式
dis1602(0,0x01); //清屏
dis1602(0,0x06); //写一个字符指针加一,光标加一
dis1602(0,0x0c); //开显示 不显示光标
print1602(0x00," 2018 08 12W.1");
print1602(0x40," 10:20:1031.7 ");
dis1602(0,0x40);
for(i1=0;i1<32;i1++)
dis1602(1,zi1602);
dis1602(0,0x85);dis1602(1,1);
dis1602(0,0x88);dis1602(1,2);
dis1602(0,0x8b);dis1602(1,3);
dis1602(0,0xcf);dis1602(1,0);
INT_CLKO|=0X40; //int4中断开关
// P3M1=1; //p3.0 高阻输入
}
void getkey1602()
{
keyy1=0; //keyy1置零
keynow=keyx1; //keynow状态等于keyx1
keynow=keyx2;
keynow=keyx3;
keynow=keyx4;
keyy1=1;
if(keynow==0&&keyold==1)
mode=0;
if(keynow==0&&keyold==1)
IAP_CONTR=0x60; //软复位
if(keynow==0&&keyold==1)
if(++set==6)
set=0;
if(keynow==0&&keyold==1)
{
switch(set)
{
case 0:year++;break;
case 1:if(++mon==13)mon=1;break;
case 2:if(++day==32)day=1;break;
case 3:if(++hour==24)hour=0;break;
case 4:if(++min==60)min=0;break;
case 5:if(++sec==60)sec=0;break;
default:break;
}
week=((year/100/4)-year/100*2+year%100+year%100/4+26*(mon+1)/10+day-1)%7;
if(week==0)
week=7;
}
keyold=keynow;
keyold=keynow;
keyold=keynow;
keyold=keynow;
}
void init()
{
P2M0=0x1B; //P2强推挽0001 1011
P3M0=0xE4; //P3强推挽1110 0100
P1ASF=0x80; //开启P1^7引脚模拟功能
key=255;
S1=0; //pwm引脚置零
EA=1; //中断总开关
ET0=1; //定时器0开关
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x88; //设置定时初值 10us
TH0 = 0xFF; //设置定时初值
TR0 = 1; //定时器0开始计时
SCON|=0x40; //0100 0000 串口1工作模式1 开启接收
ES=1; //打开串口中断
PS=1; //串口最高中断优先级
AUXR |= 0x05; //定时器时钟1T模式 定时器2为串口1波特率
T2L = 0xC8; //设置定时初值
T2H = 0xFE; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
}
uint MAX6675_ReadReg() //返回dat 0-65535 包含状态 温度值
{
uchar i;
uint dat; // 1111 1111 1111 1111
i = 0;
dat = 0;
CS= 0; //片选端,CS为低时、启动串行接口
SCK = 0; //串行时钟置零 准备输出6675收到上升沿发送数据
for(i=0; i<16; i++) //get D15-D0 from 6675从最高位开始接收16位数据
{
SCK = 1; //重置时钟 接收数据
dat = dat<<1; //dat左移一位,1111 1111 1111 1110
if( SO==1 )
dat = dat|0x01; //收到高电平,个位改为1
SCK = 0; //发送时钟信号,准备接收下一位数据
}
CS = 1;
SCK=1;
return dat; //
}
void gettemp()
{
if(count2==8) //256周期测一次温度,电压
{
temp=MAX6675_ReadReg(); //读取状态数据0-65535 1111 1111 1111 1111 fedc ba98 7654 3210
Flag_temp=(temp&4)>>2; //读出数据的D2位是热电偶掉线标志位,该位为1表示掉线,该位为0表示连接 0000 0000 0000 0100
temp=((temp<<1)>>4)*5/2; //读出来的数据的D3~D14是温度值 左移1位,右移4位 乘5/2 10倍温度值
}
}
voidgetadc()
{
ADC_CONTR=0xef; //开始ad转换 1110 1111
while(ADC_CONTR==0xef); //跳过转换时间
ADC_CONTR&=0xe7; //1110 0111 清除adc中断标志
adc=ADC_RES*4+ADC_RESL; //读取转换结果 10位精度 0-1023
}
void getkey()
{
uchar i;
if(count2%16==0) //16ms检测一次mode键
{
keyy1=0; //keyy1置零
keynow=keyx1; //keynow状态等于keyx1
keynow=keyx2;
keyy1=1;
if(keynow==0&&keyold==1)
key=0;
if(keynow==0&&keyold==1)
IAP_CONTR=0x60; //软复位
keyold=keynow;
keyold=keynow;
}
if(count2%16==0&&mode==1) //模式1时,16ms检测一次按键
{
keyy1=0;
keynow=keyx1;
keynow=keyx2;
keynow=keyx3;
keynow=keyx4;
keyy1=1;keyy2=0;
keynow=keyx1;
keynow=keyx2;
keynow=keyx3;
keynow=keyx4;
keyy2=1;keyy3=0;
keynow=keyx1;
keynow=keyx2;
keynow=keyx3;
keynow=keyx4;
keyy3=1;keyy4=0;
keynow=keyx1;
keynow=keyx2;
keynow=keyx3;
keynow=keyx4;
keyy4=1;keyy5=0;
keynow=keyx1;
keynow=keyx2;
keynow=keyx3;
keynow=keyx4;
keyy5=1;
for(i=0;i<20;i++)
{
if(keynow==0&&keyold==1)
key=i;
keyold=keynow;
}
}
}
void SendData(uchar dat)
{
while(busy); //等待前面数据发送完成
busy=1;
SBUF=dat;
}
void SendString(char *s)
{
while(*s)
{
SendData(*s++);
}
}
void INITEEP() //开始eeprom操作
{
IAP_CONTR|=0X83; //1000 0011 允许eeprom操作 延时设置为011
IAP_CONTR&=0XFB; //1111 1011
}
void BANEEP() //结束eeprom操作
{
IAP_CONTR&=0X78; //0111 1000
IAP_CMD=0;
IAP_TRIG=0;
}
void Write_EEP(uint addr,uchar dat) //地址addr,写入dat
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_DATA=dat;
IAP_CMD=2;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
}
uchar Read_EEP(uint addr) //地址addr读取数据
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_CMD=1;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
return IAP_DATA;
}
///////////////////////////////
//void Read_EEP2(uint addr) //地址addr读取数据
//{
// IAP_ADDRH=addr>>8;
// IAP_ADDRL=addr;
// IAP_CMD=1;
// IAP_TRIG=0X5A;
// IAP_TRIG=0XA5;
//}
void Write_EEP2(uint addr,uchar dat) //地址addr,写入dat
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_DATA=dat;
IAP_CMD=2;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
}
/////////////////////////////////////
void EraseSector_EEP(uint addr) //清空扇区
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_CMD=3;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
}
void RECORD_1602() //记录1602时间
{
INITEEP();
for(num=0;num<512;num+=8) //八字节一组 读第一字节
{
if(Read_EEP(sto1602+num)==0xff) //读出未写字符跳出
break;
}
value=num;
Write_EEP(sto1602+num,0); //第一字节置零
Write_EEP(sto1602+num+1,year/100);
Write_EEP(sto1602+num+2,year%100);
Write_EEP(sto1602+num+3,mon);
Write_EEP(sto1602+num+4,day);
Write_EEP(sto1602+num+5,hour);
Write_EEP(sto1602+num+6,min);
Write_EEP(sto1602+num+7,0); //最后字节置零
BANEEP();
}
void READ_1602()
{
uchar temp;
INITEEP();
for(num=0;num<512;num+=8) //八字节一组 读第一字节
{
temp=Read_EEP(sto1602+num);
if(temp==0xff) //读出未写字符跳出
break;
} //如扇区满,num=512跳出循环
if(num==0) //无数据返回
return;
while(Read_EEP(sto1602+num-1)!=0) //如果前一组不完整,前跳一组
{
num-=8;
if(num==0) //无数据返回
return;
}
num-=8; //读取空白前一组
value=num;
year=Read_EEP(sto1602+num+1)*100;
year+=Read_EEP(sto1602+num+2);
mon=Read_EEP(sto1602+num+3);
day=Read_EEP(sto1602+num+4);
hour=Read_EEP(sto1602+num+5);
min=Read_EEP(sto1602+num+6);
week=((year/100/4)-year/100*2+year%100+year%100/4+26*(mon+1)/10+day-1)%7;
if(week==0)
week=7;
if(num==504) //扇区满清空
{
EraseSector_EEP(sto1602); //清空扇区
RECORD_1602(); //记录当前数据
}
BANEEP();
}
void operation()
{
if(count2%16==0)
{
switch(key)
{
case 0: key=255;mode++;if(mode==5){mode=0;S1=0;}break;//3个模式
case 1: break;
case 2: break;
case 3: break;
case 4: key=255;x=1; break;
case 5: key=255;x=2; break;
case 6: key=255;x=3; break;
case 7: key=255;OP1=1; break; // +
case 8: key=255;x=4; break;
case 9: key=255;x=5; break;
case 10:key=255;x=6; break;
case 11:key=255;OP1=2; break; // -
case 12:key=255;x=7; break;
case 13:key=255;x=8; break;
case 14:key=255;x=9; break;
case 15:key=255;OP1=3; break; // *
case 16:key=255;x=0; break;
case 17:key=255;OP2=1; break; // =
case 18:key=255;OP2=2; break; // c
case 19:key=255;OP1=4; break; // /
default: break;
}
if(mode==1)
{
if(OP1==0&&x!=255)
{
value1=value1*10+x;
x=255;
value=value1;
}
if(OP1!=0&&x!=255)
{
value2=value2*10+x;
x=255;
value=value2;
}
if(OP2==1) //输入 =
{
OP2=0;
switch(OP1)
{
case 0: value=value1;SendString(""); break;
case 1: value=value1+value2; break;
case 2: value=value1-value2; break;
case 3: value=value1*value2; break;
case 4: value=value1/value2; break;
default: break;
}
OP1=OP2=DOP2=tOP2=value1=value2=0;
}
if(DOP2==1)
tOP2++;
if(tOP2==30)
DOP2=0;
if(OP2==2&&DOP2==1) //双击C清空所有数据
OP1=OP2=DOP2=tOP2=value1=value2=value=0;
if(OP2==2) //单击C清除数据
{
OP2=0;
DOP2=1;tOP2=0;
if(OP1==0)
value=value1=0;
else
value=value2=0;
}
}
}
}
void display()
{
if(mode==0)
{
gettemp();
switch(count) //显示温度
{
case 0:B4=1;if(temp/1000==0)break; disduan(duan); diswei(wei);break; //显示第1管 为0不显示
case 1:B1=1;disduan(duan); diswei(wei);break; //显示第2管
case 2:B2=1;disduan(duan); diswei(wei);DP=1;break; //显示第3管 带小数点
case 3:B3=1;disduan(duan); diswei(wei);break; //显示第4管
default: break;
}
}
if(mode==1)
{
switch(count) //显示按键 计算器
{
case 0:B4=1;if(value/1000==0)break; disduan(duan); diswei(wei);break; //显示第1管
case 1:B1=1;if(value/100==0)break; disduan(duan); diswei(wei);break; //显示第2管
case 2:B2=1;if(value/10==0)break; disduan(duan); diswei(wei);break; //显示第3管
case 3:B3=1; disduan(duan); diswei(wei);break; //显示第4管
default: break;
}
}
if(mode==2)
{
if(count==0)
{
getadc();
adc=adc*5000/1023; //1000倍电压值 adc*5v/1023*1000
}
switch(count) //显示电压
{
case 0:B4=1;disduan(duan); diswei(wei);DP=1;break; //显示第1管 带小数点
case 1:B1=1;disduan(duan); diswei(wei);break; //显示第2管
case 2:B2=1;disduan(duan); diswei(wei);break; //显示第3管
case 3:B3=1;disduan(duan); diswei(wei);break; //显示第4管
default: break;
}
}
while(mode==3) //模式3 pwm循环
{
t0=0;
pwmflag=!pwmflag;
if(pwmflag==1) S1=1; //pwm高电平
B4=1;disduan(duan);diswei(wei); //显示数码管1
getadc(); //获取adc 0-1023
adc=adc/10+100; //100-202
if(adc>200) //100-200
adc=200;
while(t0!=adc);
S1=0; //pwm低电平
while(t0!=250);
B1=1;disduan(duan); diswei(wei);//显示数码管2
while(t0!=500);
B2=1;disduan(duan); diswei(wei);//显示数码管3
while(t0!=750);
B3=1;disduan(duan); diswei(wei);//显示数码管4
//检测mode按键
keyy1=0; //keyy1置零
keynow=keyx1; //keynow状态等于keyx1
keynow=keyx2;
keyy1=1;
if(keynow==0&&keyold==1)
{
mode=4; //符合条件mode回零,跳出pwm模式循环
B4=1;
}
if(keynow==0&&keyold==1)
IAP_CONTR=0x60; //软复位
keyold=keynow;
keyold=keynow;
while(t0!=1000); //10ms一个周期
}
if(mode==4)
{
TL0 = 0x20; //设置定时初值 1ms
TH0 = 0xD1; //设置定时初值
init1602();
READ_1602();
while(mode==4)
{
t0=0;
getkey1602();
if(++sec==60)
{
sec=0;
min++;
// RECORD_1602();
}
dis1602(0,0xc7);dis1602(1,sec/10+0x30);dis1602(1,sec%10+0x30);
B4=1;disduan(duan);diswei(wei); //显示数码管1
while(t0!=100);
getkey1602();
if(min==60)
{
min=0;
hour++;
}
dis1602(0,0xc4);dis1602(1,min/10+0x30);dis1602(1,min%10+0x30);
while(t0!=200);
getkey1602();
if(hour==24)
{
hour=0;
day++;
if(++week==8)
week=1;
}
dis1602(0,0xc1);dis1602(1,hour/10+0x30);dis1602(1,hour%10+0x30);
B1=1;disduan(duan); diswei(wei);//显示数码管2
while(t0!=300);
getkey1602();
if((mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)&&day==32)
{
day=1;
mon++;
}
else if((mon==4||mon==6||mon==9||mon==11)&&day==31)
{
day=1;
mon++;
}
else if(((year)%4!=0||((year)%100==0&&(year)%400!=0))&&mon==2&&day==29)
{
day=1;
mon++;
}
else if(((year)%4==0&&(year)%100!=0||(year)%400==0)&&mon==2&&day==30)
{
day=1;
mon++;
}
dis1602(0,0x89);dis1602(1,day/10+0x30);dis1602(1,day%10+0x30);
while(t0!=400);
getkey1602();
dis1602(0,0x8f);dis1602(1,week+0x30);
while(t0!=500);
getkey1602();
if(mon==13)
{
mon=1;
year++;
}
dis1602(0,0x86);dis1602(1,mon/10+0x30);dis1602(1,mon%10+0x30);
B2=1;disduan(duan); diswei(wei);//显示数码管3
while(t0!=600);
getkey1602();
dis1602(0,0x83);dis1602(1,year%100/10+0x30);dis1602(1,year%10+0x30);
while(t0!=700);
getkey1602();
dis1602(0,0x81);dis1602(1,year/1000+0x30);dis1602(1,year%1000/100+0x30);
while(t0!=800);
getkey1602();
temp=MAX6675_ReadReg(); //读取状态数据0-65535 1111 1111 1111 1111 fedc ba98 7654 3210
temp=((temp<<1)>>4)*5/2; //读出来的数据的D3~D14是温度值 左移1位,右移4位 乘5/2 10倍温度值
dis1602(0,0xcb);dis1602(1,temp%1000/100+0x30);dis1602(1,temp%100/10+0x30);
while(t0!=900);
getkey1602();
dis1602(0,0xce);dis1602(1,temp%10+0x30);
B3=1;disduan(duan); diswei(wei);//显示数码管4
while(t0!=1000);
}
TL0 = 0x88; //设置定时初值 10us
TH0 = 0xFF; //设置定时初值
}
}
main()
{
init();
while(1)//
{
delay(1); //系统周期1毫秒
if(++count>3) count=0; //0-3循环
count2++; //0-255循环
getkey(); //运行一次80us16ms运行一次
operation();
display();
}
}
void Uart1_Routine() interrupt 4 using 3
{
if(RI)
{
RI=0; //清除RI标志
value=SBUF;
}
if(TI)
{
TI=0; //清除TI标志
busy=0;
}
}
void Int4_Routine() interrupt 16 using 3
{
uint num1;
IE=0;
TCON=0;
AUXR=0;
SCON=0;
P2M0=0;
P3M0=0;
B1=B2=B3=B4=1;
INITEEP();
for(num1=0;num1<512;num1+=8) //八字节一组 读第一字节
{
IAP_ADDRH=(sto1602+num1)>>8;
IAP_ADDRL=(sto1602+num1);
IAP_CMD=1;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
if(IAP_DATA==0xff) //读出未写字符跳出
break;
}
value=num1;
Write_EEP2(sto1602+num1,0); //第一字节置零
Write_EEP2(sto1602+num1+1,year/100);
Write_EEP2(sto1602+num1+2,year%100);
Write_EEP2(sto1602+num1+3,mon);
Write_EEP2(sto1602+num1+4,day);
Write_EEP2(sto1602+num1+5,hour);
Write_EEP2(sto1602+num1+6,min);
Write_EEP2(sto1602+num1+7,0); //最后字节置零
BANEEP();
// while(1)
// {
// B4=1;disduan(duan);diswei(wei); //显示数码管1
// B1=1;disduan(duan); diswei(wei);//显示数码管2
// B2=1;disduan(duan); diswei(wei);//显示数码管3
// B3=1;disduan(duan); diswei(wei);//显示数码管4
// }
}
void Timer0_Routine() interrupt 1 using 2
{
t0++; //10us
}
进来围观{:1_1:}{:1_1:} read函数里面都没有读寄存器操作,怎么可能正常呢
路过帮顶
看来是个很重要的应用。 路过看看
路过帮顶
我爱萝丽爱萝丽 发表于 2018-8-19 21:47
read函数里面都没有读寄存器操作,怎么可能正常呢
萝丽大神好{:1_12:}
如果read函数能正确读到中断里赋的值,这个子程序执行完,我只要在中断里读取IAP_DATA的值应该也是可以的。
主要的问题是中断程序里Read_EEP2(sto1602+num1);中的“sto1602+num1” 赋值给子程序void Read_EEP2(uint addr) 中的“addr”出错
sto1602的值是0x0400,也就是1024 但是读取子程序中的addr显示在数码管上才4,5之类的数
uchar Read_EEP2(uint addr) //从地址addr读取数据
{
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_CMD=1;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
return IAP_DATA;
}
这样也试过,返回的值不对。 受教了虽然还是不懂 受教了虽然还是不懂
发电子论坛吧
我新手,感觉单片机语言和我学的java差好多,直接看不懂 看不懂
yxs88q 发表于 2019-4-9 06:19
看不懂
半年没看单片机了,我自己也看不懂了哈哈{:1_9:}
页:
[1]