偿试着做了个100分钟倒计时定时器,原理图和代码都是东拼西凑来的(自己不会写啊 ),侵删
制作出来的实物图如下:
电路原理图如下:
单片机源程序如下:
#include <reg52.h>
#include <intrins.H>
#define uchar unsigned char
#define uint unsigned int
uchar duan[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchar wei[4]={0XEf,0XDf,0XBf,0X7f}; //位的控制端
uint setfen,setmiao,runfen,runmiao;
uint z,x,c,v;
uint fs,fg,ms,mg;
uint setwz;
sbit KEYSTOP=P3^7; //停止键
sbit KEYSET=P1^7; //设置键
sbit KEYUP=P1^6; //上调
sbit KEYDOWN=P1^5; //下调
sbit KEYRUN=P1^4; //开始
sbit LEDSET=P1^3; //设置灯
sbit LEDRUN=P1^2; //运行灯
sbit LEDSTOP=P1^1; //停止灯
sbit LABA=P1^0; //喇叭
uint runmod=0; //状态,0是等待运行(停止),1是运行,2是设置,3是刚刚完成
unsigned char n_50ms;
bit flag;
/****************特殊功能寄存器声明,以下是关于读写FLASH的****************/
sfr ISP_DATA = 0xe2;
sfr ISP_ADDRH = 0xe3;
sfr ISP_ADDRL = 0xe4;
sfr ISP_CMD = 0xe5;
sfr ISP_TRIG = 0xe6;
sfr ISP_CONTR = 0xe7;
void cc(uint addr);
void xcx(uint addr,uchar dat);
uchar dcx(uint addr);
void Q0();
/******************************************************************
延时函数
******************************************************************/
void delay(uchar t)
{
uchar i,j;
for(i=0;i<t;i++)
{
for(j=13;j>0;j--);
{ ; }
}
}
/**********使用定时器显示数字*********************/
void timer_display(uchar gw)
{
if(runmod==2)
{
z=setfen/10; //求分十位
x=setfen%10; //求分个位
c=setmiao/10; //求秒十位
v=setmiao%10; //求秒个位
}
else
{
z=runfen/10; //求分十位
x=runfen%10; //求分个位
c=runmiao/10; //求秒十位
v=runmiao%10; //求秒个位
}
if(gw==1 && (z>0 || runmod==2))
{
P2=wei[0];
if(runmod==2 && setwz==1)
{
if(flag)
{P0=duan[z];}
else
{P0=0xFF;}
}
else {P0=duan[z];}
}
else if(gw==2 && (x>0 || z>0 || runmod==2))
{
P2=wei[1];
if(runmod==2 && setwz==1)
{
if(flag)
{P0=duan[x];}
else
{P0=0xFF;}
}
else {P0=duan[x];}
}
else if(gw==3 && (c>0 || x>0 || runmod==2))
{
P2=wei[2];
if(runmod==2 && setwz==0)
{
if(flag)
{P0=duan[c];}
else
{P0=0xFF;}
}
else {P0=duan[c];}
}
else if(gw==4)
{
P2=wei[3];
if(runmod==2 && setwz==0)
{
if(flag)
{P0=duan[v];}
else
{P0=0xFF;}
}
else
{P0=duan[v];}
}
}
void Timer0_Init()
{
TMOD|=0X01;
TH0=60928/256;
TL0=60928%256;//每5ms进入一次中断
TF0=0;
TR0=1;
EA=1;
ET0=1; //TF0 如果这个标志为1,进入中断子函数
}
void tshow()
{
static char i=0;
i++;
timer_display(i);
if(i>=4)
{
i=0;
}
}
void TF0_isr() interrupt 1
{
TH0=60928/256;
TL0=60928%256;//重装初值
tshow();
}
void Timer1_Init()
{
TMOD|=0x10; //定时器1方式1,计数与否不受P3.3的影响
TH1=(65536-50000)/256; //50ms
TL1=(65536-50000)%256;
TF1=0;
ET1=1;
TR1=1;
}
void TF1_isr() interrupt 3
{
TH1=(65536-50000)/256; //50ms
TL1=(65536-50000)%256;
n_50ms++;
if(runmod==2)
{
n_50ms %= 5; //10对应1Hz
if(!n_50ms) flag = ~flag;
}
else if(runmod==1)
{
n_50ms %= 20; //
if(!n_50ms)
{
if(runmiao>0) runmiao--;
if(runmiao==0)
{
if(runfen>0)
{
runmiao=59;
runfen--;
}
}
if(runfen==0 && runmiao==0)
{
runmod=3; //状态改为到时
LEDRUN=0; //运行灯灭
LEDSTOP=1; //停止灯亮
}
}
}
else if(runmod==3) //到时,喇叭响
{
n_50ms %= 5; //10对应1Hz
if(!n_50ms)
{
LABA=!LABA;
}
}
}
void key() //按键扫描函数
{
if(runmod==0) //停止状态下
{
if(KEYSET==0) //设置键
{
delay(100);
if(KEYSET==0)
{
LEDSTOP=0;
LEDRUN=0;
LEDSET=1;
runmod=2;
setwz=0;
while (KEYSET==0)
{ delay(100);}
Timer1_Init();
}
}
else if(KEYRUN==0) //开始运行
{
delay(100);
if(KEYRUN==0)
{
runfen=setfen;
runmiao=setmiao;
runmod=1;
LEDSTOP=0;
LEDRUN=1;
LEDSET=0;
while (KEYRUN==0)
{ delay(100);}
Timer1_Init();
}
}
}
else if(runmod==1 || runmod==3) //运行或到时状态
{
if(KEYSTOP==0) //按下停止
{
delay(100);
if(KEYSTOP==0)
{
ET1=0;
TR1=0;
runmod=0;
LEDSTOP=1;
LEDRUN=0;
LEDSET=0;
LABA=0;
while (KEYSTOP==0)
{ delay(100);}
}
}
}
else if(runmod==2) //设置状态
{
if(KEYRUN==0) //前移
{
delay(10);
if(KEYRUN==0)
{
setwz++;
if(setwz>1) {setwz=0;}
while (KEYRUN==0){ delay(10);}
}
}
else if(KEYUP==0) //增加
{
delay(10);
if(KEYUP==0)
{
if(setwz==0)
{
if(setmiao<59) setmiao++;
else
setmiao=0;
}
else if(setwz==1)
{
if(setfen<99) setfen++;
else
setfen=0;
}
while (KEYUP==0) { delay(10);}
}
}
else if(KEYDOWN==0) //减少
{
delay(10);
if(KEYDOWN==0)
{
if(setwz==0)
{
if(setmiao>0) setmiao--;
else setmiao=59;
}
else if(setwz==1)
{
if(setfen>0) setfen--;
else setfen=99;
}
while (KEYDOWN==0) { delay(10);}
}
}
else if(KEYSET==0) //设置完成
{
delay(10);
if(KEYSET==0)
{
while (KEYSET==0) { delay(10);}
ET1=0;
EA=0;
TR1=0;
flag=1;
fs=setfen/10; //求分十位
fg=setfen%10; //求分个位
ms=setmiao/10; //求秒十位
mg=setmiao%10; //求秒个位
cc(0x2000);
xcx(0x2001,fs);
xcx(0x2002,fg);
xcx(0x2003,ms);
xcx(0x2004,mg);
Q0();
LEDSTOP=1;
LEDSET=0;
LEDRUN=0;
runmod=0;
Timer0_Init();
}
}
}
}
/*************************************************************************
主函数
**************************************************************************/
void main()
{
fs = dcx(0x2001); // 开机读取EEPROM区2002h数据
fg = dcx(0x2002);
ms = dcx(0x2003);
mg = dcx(0x2004);
setfen=fs*10+fg;
setmiao=ms*10+mg;
runmod=0;
LEDSET=0;
LEDSTOP=1;
LEDRUN=0;
LABA=0;
Timer0_Init();
flag=1;
setwz=0;
while(1)
{
key();
}
}
|