|
#include <reg52.h> //用52的頭文件 里面加的引腳再定義
#include "intrins.h" //延時(shí)
sfr AUXR = 0x8e;
sfr P5 = 0xc8; //p5定義 是加的
sfr P5M0 = 0xc9;
sfr P5M1 = 0XCA;
sfr P3M0 = 0xb2; //p3口設(shè)置強(qiáng)推完的定義
sfr P3M1 = 0Xb1;
sfr P1M0 = 0x92; //p0口設(shè)置強(qiáng)推完的定義 這樣設(shè)置數(shù)碼管就亮
sfr P1M1 = 0X91;
/***********************掉電存儲(chǔ)開始********************/
typedef unsigned char BYTE;
typedef unsigned int WORD; //類型定義
unsigned char x = 0;
sfr IAP_DATA = 0xC2; //IAP數(shù)據(jù)寄存器
sfr IAP_ADDRH = 0xC3; //IAP地址寄存器高字節(jié)
sfr IAP_ADDRL = 0xC4; //IAP地址寄存器低字節(jié)
sfr IAP_CMD = 0xC5; //IAP命令寄存器
sfr IAP_TRIG = 0xC6; //IAP命令觸發(fā)寄存器
sfr IAP_CONTR = 0xC7; //IAP控制寄存器
#define CMD_IDLE 0 //空閑模式
#define CMD_READ 1 //IAP字節(jié)讀命令
#define CMD_PROGRAM 2 //IAP字節(jié)編程命令
#define CMD_ERASE 3 //IAP扇區(qū)擦除命令
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
#define IAP_ADDRESS 0x0400 //測(cè)試地址
//void Delay(BYTE n);
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);
/***********************掉電存儲(chǔ)結(jié)束****************/
/*****************************數(shù)碼管開始***********************************/
unsigned int i = 0;//用于掃描數(shù)碼管
unsigned char bainum1 = 0;//百
unsigned char shinum1 = 0;//十
unsigned char genum1 = 0;//個(gè)
sbit pa = P1^0;sbit pb = P3^2;sbit pc = P3^7;sbit pd = P1^3;//數(shù)碼管段
sbit pe = P1^2;sbit pf = P1^4;sbit pg = P3^3;//數(shù)碼管段
sbit p1 = P1^1;sbit p2 = P3^6;sbit p3 = P5^5;//數(shù)碼管位
void s0();void s1();void s2();void s3();void s4();void s5();//數(shù)碼管部分
void s6();void s7();void s8();void s9();void s10();//數(shù)碼管部分
void xuaze(unsigned char j);//數(shù)碼管段顯示
void displaynum(unsigned int);//顯示函數(shù)
//unsigned char code duan [] ={0,1,2,3,4,5,6,7,8,9};
unsigned int bainum11=0,shinum11=0,genum11=0;//用于傳到數(shù)碼管上顯示
/*****************************數(shù)碼管結(jié)束***********************************/
unsigned int inum1=0,inum2=0;//觸發(fā)端子用的計(jì)數(shù)
unsigned char inum11=0,inum12=0,inum21=0,inum22=0,ss=0;//掉電存儲(chǔ)要用到
static unsigned char presstime=0;//時(shí)間值按鍵用到的
unsigned int kf0=1;//按鍵用的標(biāo)志位
unsigned int kt0=0;//按鍵用的標(biāo)志位
unsigned int if0=1,if0s=1,it0=0;
unsigned int mm=0,ff=0,sss=0;//計(jì)數(shù)用
bit flag_eeprom1=1;//掉電存儲(chǔ)的標(biāo)志位
unsigned int keynum=0;//數(shù)碼管的位
sbit key2=P3^0;//按鍵
sbit key1=P3^1;//按鍵
sbit out= P5^4;//輸出
void timer0_1init();//定時(shí)器聲明
void keycan();//按鍵
void keyflag();//按鍵結(jié)束調(diào)用
void saveeepro();//掉電存儲(chǔ)
extern void displaynums();//將數(shù)字傳到數(shù)碼管上顯示
void main()
{
timer0_1init();
P3M0 = 0xcc;
P3M1 = 0X00; //p3口設(shè)置強(qiáng)推挽
P1M0 = 0x1f;
P1M1 = 0X00;
inum11 = IapReadByte(1);//讀取掉電存儲(chǔ)里的值
inum12 = IapReadByte(2);
inum21 = IapReadByte(3);
inum22 = IapReadByte(4);
if0 = IapReadByte(5);
if0s = IapReadByte(6);
ss = IapReadByte(7);
inum1=inum11*100+inum12;//組合掉電存儲(chǔ)中的值
inum2=inum21*100+inum22;
bainum11=inum1/100;//傳到數(shù)碼管顯示
shinum11=inum1/10%10;
genum11=inum1%10;
while(1){
keycan();//按鍵
}
}
void keycan(){//按鍵
if(keynum==0){//當(dāng)按鍵值等于0的時(shí)候調(diào)用顯示
displaynums();//數(shù)碼管的顯示
if(if0s==0){//當(dāng)if0s等于0時(shí),繼電器輸出
out=0;
}
if((flag_eeprom1==1)){//加掉電存儲(chǔ)
saveeepro();//掉電存儲(chǔ)
flag_eeprom1=0;
}
}
if(key1==0){//當(dāng)按鍵1按下
if(kf0){//當(dāng)標(biāo)志位kf0=1的時(shí)候進(jìn)行
if(presstime>50){//當(dāng)時(shí)間值大于一百的時(shí)候
kf0=0;//標(biāo)志位kf0=0
kt0=1;//標(biāo)志位kt0=0
flag_eeprom1=1;if0s=1;out=1;if0=1;
presstime=0;//時(shí)間清零,重新進(jìn)行
keynum++;//數(shù)碼管的位
if(keynum==4){//當(dāng)位到4則置位0
keynum=0;
if0=0;
}
if(out==0){
if0=0;
}
}
}
}else{//當(dāng)按鍵松開
keyflag();
if((flag_eeprom1==1)){ //加掉電存儲(chǔ),必需加到這,不然有一些小問題
flag_eeprom1=0;
saveeepro();//掉電存儲(chǔ)
}
}//按鍵1結(jié)束
if(key2==0){if(kf0){if(presstime>50){kf0=0;kt0=1;presstime=0;flag_eeprom1=1;//掉電存儲(chǔ)的標(biāo)志位改為1,進(jìn)行存值操作
// if(out==0){
// if0=0;if0s=1;out=1;
// }
switch(keynum){
case 1:
bainum11++;//數(shù)碼管一加加
if(bainum11>9){//當(dāng)數(shù)碼管一加加到9時(shí)置為1
bainum11=0;
}
break;
case 2:shinum11++;if(shinum11>9){shinum11=0;}break;
case 3:genum11++;if(genum11>9){genum11=0;}break;
default:break;
}
}}}else{keyflag();displaynums();
if((flag_eeprom1==1))//加掉電存儲(chǔ),必需加到這,不然有一些小問題
{ flag_eeprom1=0;
saveeepro();//掉電存儲(chǔ)
}
}//松開按鍵進(jìn)行顯示
}
void tm0_isr() interrupt 1 using 1
{//500等1s
TL0 = 0x18; //設(shè)置定時(shí)初值
TH0 = 0xFC; //設(shè)置定時(shí)初值
presstime++;
i++;
if (if0==0){//當(dāng)if0==0時(shí)開始倒計(jì)時(shí)
mm++;
if(mm==500){//一秒時(shí)間到
mm=0;
ff++;
if(ff>60){//一分鐘
ff=0;
sss++;
ss=sss;
flag_eeprom1=1;
if(sss>60){//一小時(shí)
sss=0;
inum2--;
flag_eeprom1=1;
if(inum2==0){
if0s=0;//繼電器輸出
if0=1;//返回設(shè)置的時(shí)長(zhǎng)
flag_eeprom1=1;
}
}
}
}
}
switch (i){
case 1: s10(); xuaze(bainum1); if(keynum==1 || keynum==0){p1 = 0;}p2 = 1;p3 = 1;break;
case 2: s10(); xuaze(shinum1); if(keynum==2 || keynum==0){p2 = 0;}p1 = 1;p3 = 1;break;
case 3: s10(); xuaze(genum1); if(keynum==3 || keynum==0){p3 = 0;}p1 = 1;p2 = 1;break;
default:i=0;s10(); break;
}
}
void timer0_1init(){//定時(shí)器聲明
TMOD=0x11;//將定時(shí)器0,1都設(shè)置為模式1
TL0 = 0x18; //設(shè)置定時(shí)初值
TH0 = 0xFC; //設(shè)置定時(shí)初值
TR0=1;//開啟定時(shí)器0
TR1=1;//開啟定時(shí)器1
EA=1;//開總中斷
ET0=1;//開定時(shí)器0的中斷
}
/**********************數(shù)碼管顯示部分開始**************************/
void displaynums(){//將數(shù)字傳到數(shù)碼管上顯示
if (if0==0){//當(dāng)if0==0時(shí)num1三個(gè)數(shù)碼管進(jìn)行顯示
genum1=inum2%10;//個(gè)位
shinum1=inum2/10%10;//十位
bainum1=inum2/100;//百
}else{
bainum1=bainum11;
shinum1=shinum11;
genum1=genum11;
inum1=bainum11*100+shinum11*10+genum11; //將num1三個(gè)數(shù)碼管的值付給inum
inum2=inum1;
}
}
void s0(){pa = 1;pb = 1;pc = 1;pd = 1;pe = 1;pf = 1;pg = 0;}
void s1(){pb = 1;pc = 1;pa = 0;pg = 0;pd = 0;pe = 0;pf = 0;}
void s2(){pa = 1;pb = 1;pg = 1;pe = 1;pd = 1;pf = 0;pc = 0;}
void s3(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 0;pe = 0;}
void s4(){pb = 1;pg = 1;pc = 1;pf = 1;pa = 0;pd = 0;pe = 0;}
void s5(){pa = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 0;pb = 0;}
void s6(){pa = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 1;pb = 0;}
void s7(){pa = 1;pb = 1;pc = 1;pf = 0;pe = 0;pd = 0;pg = 0;}
void s8(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 1;}
void s9(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 0;}
void s10(){pa =0;pb = 0;pc = 0;pf = 0;pe = 0;pd = 0;pg = 0;}
void xuaze(unsigned char j){
if(j == 0){s0();}
else if(j == 1){s1();}
else if(j == 2){s2();}
else if(j == 3){s3();}
else if(j == 4){s4();}
else if(j == 5){s5();}
else if(j == 6){s6();}
else if(j == 7){s7();}
else if(j == 8){s8();}
else if(j == 9){s9();}}
/**********************數(shù)碼管顯示部分結(jié)束**************************/
/**********************掉電存儲(chǔ)部分開始**************************/
//掉電存儲(chǔ)
//void Delay(BYTE n){
// WORD x;
// while (n--){x = 0;while (++x);}
//}
//關(guān)閉IAP
void IapIdle(){
IAP_CONTR = 0; //關(guān)閉IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除觸發(fā)寄存器
IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
IAP_ADDRL = 0;
}
//從ISP/IAP/EEPROM區(qū)域讀取一字節(jié)
BYTE IapReadByte(WORD addr){
BYTE dat; //數(shù)據(jù)緩沖區(qū)
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5
_nop_(); //等待ISP/IAP/EEPROM操作完
dat = IAP_DATA; //讀ISP/IAP/EEPROM數(shù)據(jù)
IapIdle(); //關(guān)閉IAP功能
return dat; //返回
}
//寫一字節(jié)數(shù)據(jù)到ISP/IAP/EEPROM區(qū)域
void IapProgramByte(WORD addr, BYTE dat){
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_DATA = dat; //寫ISP/IAP/EEPROM數(shù)據(jù)
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5
_nop_(); //等待ISP/IAP/EEPROM操作完
IapIdle();
}
//扇區(qū)擦除
void IapEraseSector(WORD addr){
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5
_nop_(); //等待ISP/IAP/EEPROM操作完
IapIdle();
}
void saveeepro(){//掉電存儲(chǔ)
inum11=inum1/100;//把int型的值拆分到char型
inum12=inum1%100;
inum21=inum2/100;
inum22=inum2%100;
IapEraseSector(0);
IapProgramByte(1, inum11);//數(shù)值1
IapProgramByte(2, inum12);
IapProgramByte(3, inum21);
IapProgramByte(4, inum22);
IapProgramByte(5, if0);//倒計(jì)時(shí)的狀態(tài)
IapProgramByte(6, if0s);//繼電器的狀態(tài)
IapProgramByte(7, ss);//存分
}
/**********************掉電存儲(chǔ)部分結(jié)束**************************/
void keyflag(){//按鍵結(jié)束調(diào)用,按鍵的建議使用,這樣可以減小code,但是觸發(fā)的不建議
if(kt0){//當(dāng)標(biāo)志位kt0=1的時(shí)候進(jìn)行
if(presstime>50){//當(dāng)時(shí)間值大于一百的時(shí)候
kf0=1;//標(biāo)志位kf0=1
kt0=0;//標(biāo)志位kt0=0
presstime=0;//時(shí)間清零,重新進(jìn)行
}
}
}
|
|