/* 程序名 * 倒计时程序
* 编写人 * zying
* 日 期 * 2010-10-1
2010-10-1 1、HY-536开发板调试成功
2011-1-27 2、重新编译
特点:带24c02掉电保存的倒计时程序,闪烁调节数码管,全部用中断用定时器扫描显示,
按键功能强大,有快/慢调功能,加入分、秒计数功能,利用内部EEPROM储存数据*/
/********************************************************/
#include<INC\STC12C5410AD.h>
#include<intrins.h>
/***********声明函数*************/
#define uchar unsigned char
#define uint unsigned int
uchar aa,flag,flag1,flash,flash1,flash2;
uchar aa,t1,t0,t3,t4,t5,t6,t7,t8,t9;
uint t2;
bit bz0,bz1,bz2,bz3,bz4,bz5,bz6;
uchar code d[] =
{
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0xbf,
};
uchar sz[2] = {00,00};
uchar smg[4];//时间缓冲区,初始化显示00.00
sbit up = P3^5;//减
sbit down = P3^4;//加
sbit set = P3^7;//设置
sbit out = P1^0;//输出
sbit z_h = P3^2;//分、秒计数转换
/***********数码管扫描***********/
void display()
{
smg[0] = sz[0]%10;
smg[2] = sz[0]/10; //秒
smg[1] = sz[1]%10;
smg[3] = sz[1]/10; //分
}
void ISP_write(uint ISP_addr,uchar ISP_data)//stc12c5404启始地址2000h ;2写
{
ISP_DATA = ISP_data; //送数据
ISP_ADDRL = ISP_addr%256;
ISP_ADDRH = ISP_addr/256;//送高低地址
ISP_CONTR = 0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD = 2;//写字节模式
ISP_TRIG = 0x46;
ISP_TRIG = 0xB9;//触发启动ISP
_nop_();//等待写入
ISP_CONTR = 0x00;//禁止ISP/IAp操作
ISP_CMD = 0;
ISP_TRIG = 0x00;
}
uchar ISP_read(uint ISP_addr)//stc12c5404启始地址2000h ;IAP_CMD 1读
{
uchar recivedata;
ISP_ADDRL = ISP_addr%256;
ISP_ADDRH = ISP_addr/256;//送高低地址
ISP_CONTR = 0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD = 1;//读字节模式
ISP_TRIG = 0x46;
ISP_TRIG = 0xB9;//触发启动ISP
_nop_();//等待读
recivedata = ISP_DATA;
ISP_CONTR = 0x00;//禁止ISP/IAp操作
ISP_CMD = 0;
ISP_TRIG = 0x00;
return recivedata;
}
void ISP_erase(uint ISP_addr)//stc12c5404启始地址2000h ;3擦除
{
ISP_ADDRL = ISP_addr%256;
ISP_ADDRH = ISP_addr/256;//送高低地址
ISP_CONTR = 0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD = 3;//擦除模式
ISP_TRIG = 0x46;
ISP_TRIG = 0xB9;//触发启动ISP
_nop_();//等待擦除
ISP_CONTR = 0x00;//禁止ISP/IAp操作
ISP_CMD = 0;
ISP_TRIG = 0x00;
}
/************主程序*************/
void main(void)
{
TMOD = 0x11;//启用定时1
ET0 = 1;
TR0 = 1;
TH0 = (65536-3000)/256;//1ms定时初值
TL0 = (65536-3000)%256;
EA = 1;//开中断
sz[0] = ISP_read(0x2000);
sz[1] = ISP_read(0x3000);
while(1)
{
display();
}
}
/*************定时器0中断,用做显示************/
void timer0() interrupt 1 // 定时器0中断是1号
{
uchar flag0;
TH0=(65536-3000)/256;//1ms定时初值
TL0=(65536-3000)%256;
t0 ++;
t8 ++;
if(t0 == 20)//变频处理
{
t0 = 0;
t1 ++;
t2 ++;
t3 ++;
t4 ++;
t5 ++;
t6 ++;
t7 ++;
t9 ++;
}
if(set != 0)//防止按键累加
{
t1 = 0;
bz0 = 0;
}
/***********设置键处理*************/
if((!set) && (!bz0))//同时2条件满足,才t1加1。防止在关闭状态下设置。
{
if(t1 == 20)//让t1产生一定时间翻转,用于按键长按功能状态。
{
t1 = 0;
aa ++; //长按aa加1,用于温度调节选项转换。
bz0 = 1; //bz0为1,用于按键长按时间翻转。
if(!set)
{
bz0 = 1;
}
}
}
/***********开关组合键处理*************/
if((up != 0) && (down != 0))
{
t8 = 0;
bz5 = 0;
}
if((!up || !down) && (!aa) && (!bz5))//只要同时三条件满足,t8加1。加、减按键都可以开启、关闭。
{
if(t8 == 10)
{
t8 = 0;
sz[0] = ISP_read(0x2000);
sz[1] = ISP_read(0x3000);
bz5 = 1;//锁住按键,禁止翻转。
bz4 = ~bz4;
out = 0;//控制开关
}
}
/***********倒计数************/
if(!aa)//如果aa为0
{
t3 = 0;//闪烁复位,否则影响转换时间。
flash = 0;
flash1 = 0;
if(t9 == 8)
{
t9 = 0;
flash2 = ~flash2;//小数点闪烁
}
if((sz[0] || sz[1]) && (bz4 != 0))
{
if(z_h == 0)//分、秒计数转换
{
if(bz6 == 0)//t2归零
{
t2 = 0;
bz6 = 1;
}
if(t2 == 16)//计数时间
{
t2 = 0;
sz[0]--;//减1
if(sz[0] >= 59)
{
sz[0] = 59;
sz[1] --;//减1
}
if(sz[1] == -1)
{
sz[1] = 0;
}
}
}
else//分、秒计数转换
{
if(bz6 == 1)//t2归零
{
t2 = 0;
bz6 = 0;
}
if(t2 == 1000)//计数时间
{
t2 = 0;
sz[0]--;//减1
if(sz[0] >= 59)
{
sz[0] = 59;
sz[1] --;//减1
}
if(sz[1] == -1)
{
sz[1] = 0;
}
}
}
}
else
{
bz4 = 0;
if(!aa)
{
t9 = 0;
t2 = 0;
flash = 0;
flash1 = 0;
flash2 = 0;
smg[0] = 10; //"-"
smg[1] = 10; //"-"
smg[2] = 10; //"-"
smg[3] = 10; //"-"
out = 1;
}
}
}
/***********调整位闪烁************/
else
{
if(flag || flag1)//如一个条件成立,调整位闪烁
{
out = 1;
t2 = 0;//倒计数复位,否则影响转换时间。
if(t3 == 12)//0.5s一次
{
t3 = 0;
if(flag == 1)
{
flash = ~flash;
}
if(flag1 == 1)
{
flash1 = ~flash1;
}
}
}
}
if(aa == 1)
{
sz[0] = ISP_read(0x2000);
flash2 = 0;
flag = 1;
flag1 = 0;
flash1 = 0;
if(!up)
{
flash = 0;
}
if((!up) && (!bz1))
{
bz1 = 1;
sz[0] = ISP_read(0x2000);
sz[0]++;
if(sz[0] > 59)//大于59清零
sz[0] = 0;
ISP_erase(0x2000);//擦除
ISP_write(0x2000,sz[0]);
}
if(!down)
{
flash = 0;
}
if((!down) && (!bz1))
{
bz1 = 1;
sz[0] = ISP_read(0x2000);
sz[0]--;
if(sz[0] == -1)//大于59清零
sz[0] = 59;
ISP_erase(0x2000);//擦除
ISP_write(0x2000,sz[0]);
}
}
if(aa == 2)
{
sz[1] = ISP_read(0x3000);
flash2 = 0;
flag = 0;
flag1 = 1;
flash = 0;
if(!up)
{
flash1 = 0;
}
if((!up) && (!bz1))
{
bz1 = 1;
sz[1] = ISP_read(0x3000);
sz[1] ++;
if(sz[1] >= 100)//大于59清零
sz[1] = 0;
ISP_erase(0x3000);//擦除
ISP_write(0x3000,sz[1]);
}
if(!down)
{
flash1 = 0;
}
if((!down) && (!bz1))
{
bz1 = 1;
sz[1] = ISP_read(0x3000);
sz[1]--;
if(sz[1] == -1)//大于-1
sz[1] = 99;
ISP_erase(0x3000);//擦除
ISP_write(0x3000,sz[1]);
}
}
if(aa == 3)
{
aa = 0;
flag = 0;
flag1 = 0;
flash = 0;
flash1 = 0;
}
//**********按键快/慢调处理。***********/
if((up != 0) && (down != 0))
{
bz1 = 0;
t4 = 0;
bz3 = 0;
}
if((t4 == 12) && (!bz3))//延时后加快数字变化。
{
t5 = 0;//决定数字转换变化速度
bz3 = 1;
}
if((t5 == 4) && (bz3 == 1))//数字变化速度。
{
t5 = 0;
bz1 = ~bz1;
}
if((set != 0) && (up != 0) && (down != 0))//无键按下延时复位
{
if(t6 == 250)
{
t6 = 0;
aa = 0;
}
}
else
t6 = 0;
/**********显示扫描*********/
switch(flag0)
{
case 0x00:P1 = d[smg[0]]|flash;
P2 = 0xfe;
flag0++;
break;
case 0x01:P1 = d[smg[1]]|flash1;
P2 = 0xfd;
flag0++;
break;
case 0x02:P1 = d[smg[2]]|flash;
P2 = 0xfb;
flag0++;
break;
case 0x03:P1 = d[smg[3]]|flash1;
P2 = 0xf7;
flag0++;
break;
case 0x04:P1 = 0x7f|flash2; //小数点的位置 //小数点闪烁
P2 = 0xfd;
flag0 = 0;
break;
}
}