償試著做了個100分鐘倒計時定時器,原理圖和代碼都是東拼西湊來的(自己不會寫啊 ),侵刪
制作出來的實物圖如下:
1.JPG (36.27 KB, 下載次數: 64)
下載附件
2020-1-20 10:08 上傳
電路原理圖如下:
DaoJiShi4.jpg (189.01 KB, 下載次數: 67)
下載附件
2020-1-20 10:10 上傳
單片機源程序如下:
#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();
}
}
|