uchar TC_20ms;20毫秒计数
uchar TC_100ms;100毫秒计数
uchar TC_1s;1秒计数
uchar TC_60s;60秒计数
uchar TC_3600s;1小时计数
uchar TF_200ms;20毫秒到时标记
uchar TF_100ms;100毫秒到时标记
uchar TF_1s;1秒到时标记
uchar TF_60s;60秒到时标记
uchar TF_3600s;1小时到时标记
用定时器定时产生20ms定时
void init() interrupt 1
//定时常数=65535-(晶体频率/分频数*定时周期激禅虚)明燃-20
{
//袭宴重装定时器;
TF_20MS=1;
TC_20MS++
if(TC_20MS==5){TC_20MS=0
TF_100MS=1
TC_100MS++
if(GC_100MS==10)
{TC_100MS=0
TF_1S=1
TC_1S++
if(TC_1S==60){
TC_1S=0
…………
}
}
}
}
main()
{
unsigned long waiting_time_s=10000
unsigned long beep_time_100ms=100
unsigned long sys_time_s
unsigned long beep_100ms
//初始化定时器
while(1)
{
if(TF_1S==1){sys_time_s++TF_1S=0}
if(sys_time_s>=waiting_time_s)
{
if(TF_100MS==1){beep_100ms++TF_100MS=0}
if(beep_time_100ms>beep_100ms)
beep()//响铃函数
}
}
}
///仅仅是思路,希望有帮助。
通过了,自己对照看看问题出在哪里。ORG 00H
LJMP MAIN
ORG 0003H
LJMP EINT0
ORG 0013H
LJMP EINT1
ORG 1BH
LJMP TIMER1
ORG 0100H
MAIN:SETB EA开所有中断
SETB PX0使int0为高级中断,start(int0高于1)
SETB PX1使int1为高级中断,pause
SETB IT0int0负边沿触发
SETB IT1int1负边沿触发
MOV SP,#60H给指针设置初始地址
MOV R0,#00H初始化R0
MOV R1,#00H
READY:MOV A,#00000011B开始输入数值,并使用P1.0和P1.1
MOV P1,A
MOV A,P1读键盘状困握态
JB ACC.0,L1若ACC.0为1,跳转至L1,否则个位键按下执行下条指令
LCALL PROM0若个位键按下,则跳转RPOM0,并返回R0
L1:JB ACC.1,L2若ACC.1为1,跳转至L2,否则个位键按下执行下条指令
LCALL PROM1若十位键按下,则跳转RPOM1,并返回R1
L2:MOV DPTR,#DTAB数据表格起始地址送DPTR
MOV A,R0把R0里的数给A,用于查表偏移量
MOVC A,@A+DPTR查表后相应数值给A
MOV P0,A送P0口显示
MOV A,R1把R1里的数给A,用于查表偏移量
MOVC A,@A+DPTR查表后相应数值给A
MOV P2,A送P2口显示
LCALL READY跳转回READY检查是否有按键再次按下
DTAB:DB 3FH,06H,5BH,4FH,66H共阴极数码管从0~9表
DB 6DH,7DH,07H,7FH,6FH
PROM0:LCALL DY12MS防抖动
INC R0若个位键按颤指下,汪洞庆则使R0+1
CJNE R0,#0AH,CTN如果R0=10,则执行下一条指令,否则跳转
MOV R0,#00H给R0重置0
CTN:RET
PROM1:LCALL DY12MS
INC R1若个位键按下,则使R1+1
CJNE R1,#06H,CNT如果R1=6,则执行下一条指令,否则跳转
MOV R1,#00H给R1重置0
CNT:RET
DY12MS:MOV R7,#18H延时12MS子程序
DYMS1:MOV R6,#0FFH
DYMS2:DJNZ R6,DYMS2
DJNZ R7,DYMS1
RET
EINT0:PUSH ACC
PUSH PSW
CLR TR1
POP PSW
POP ACC
SETB EX0
RETI
EINT1:ANL TMOD,#0FH计数器置为方式1,定时器模式,与INT0有关
ORL TMOD,#90H
MOV TH1,#3CH装入时间常数,0.05S
MOV TL1,#0AFH
MOV B,#0AH
MOV A,R1
MUL AB把十位分乘十
ADD A,R0
MOV B,#1200.05s*2*60
MOV R3,A
MOV R4,B
SETB TR1启T1计数
LOOP:CJNE R4,#00H,LOOP每当过1分钟后,才进入R3
CJNE R3,#00H,L3
SETB P3.0让P3.0口为1,输出高电压给蜂鸣器
LCALL DY2S让蜂鸣器鸣叫2S
RETI
L3:CLR P3.0输出低电平,使蜂鸣器不工作
SJMP LOOP
TIMER1:CLR TR1关计数控制位
DEC R4
CJNE R4,#00H,L4R4不为零,则R3不减
DEC R3
L4:MOV TL1,#0AFH装入时间常数
MOV TH1,#3CH
SETB TR1开计数控制位
RETI
DY2S:MOV R7,#200延时2S子程序
DY2S1:MOV R6,#20
DY2S2:MOV R5,#124
DY2S3:DJNZ R5,DY2S3
DJNZ R6,DY2S2
DJNZ R7,DY2S1
RET
END
#include<reg52.h>#define uint unsigned int
#define uchar unsigned char
#define START 0 //开始
#define SETTIME 1 //设置时间
#define SETCLOCK 2 //设置闹钟时间
#define DATE3 //年月日
#define DAOJISHI4 //倒计时
sbit adrd=P3^7 //IO口定义
sbit adwr=P3^6
sbit diola=P2^5
sbit dula=P2^6
sbit wela=P2^7
sbit dawr=P3^6
sbit beep=P2^3
sbit hongwai=P3^2
uint num
uchar sec
uchar min
uchar hour//时 分 秒
uchar j,k
uchar a,b
uchar set_hour
uchar set_min
uchar set_sec //困顷闹钟设置的时 分 秒
uchar dao_hour
uchar dao_min
uchar dao_sec //倒计时的时 分 秒
uint nian
uchar yue
uchar ri //年 月 日
uchar qiehuan //第一个键按下计数,值不同,按后面三个键有不同的动作
uchar TIANSHU //每个月的天数,会根据年月的不同而不同
uchar djskaishi
uchar HWflag
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} //数码管编码0--9
//函数声明物谨
void VarInit(void)
void display(uchar,uchar,uchar)
void TimerInit(void)
void delay(unsigned char i)
void delay10ms(void)
void delayhw(void)
void KeyBord(void)
void NeiRongQieHuan(void)
void ShiFenMiaoPanduan(void)
void DatePanduan(void)
void Hongwai(void)
//延时程序
void delay(unsigned char i)
{
for(j=ij>0j--)
for(k=125k>0k--)
}
//用于按键延时消抖的函数
void delay10ms(void)
{
for(a=225a>0a--)
for(b=225b>0b--)
}
//红外延罩尺基时
void delayhw(void)
{
uchar a,b
for(a=90a>0a--)
for(b=90b>0b--)
}
//主函数
int main()
{
VarInit()
TimerInit()
while(1)
{
DatePanduan()
// Hongwai()
ShiFenMiaoPanduan()
KeyBord()
NeiRongQieHuan()
}
return 0
}
void VarInit(void)
{
num = 0
sec = 0
min = 0
hour = 0
beep = 1
qiehuan = 0
set_hour = 1
set_min = 1
set_sec = 1
dao_hour = 0
dao_min = 30
dao_sec = 0 //倒计时初值
nian = 2011
yue = 6
ri = 9
TIANSHU = 30 //月份的初始值为6月
djskaishi = 0
HWflag = 1
}
void TimerInit(void)
{
EA=1 //开总中断
ET1=1
TMOD=0x01//选择计数器工作方式,选为方式1,16位计数器
TH1=0x4C //装入高八位数
TL1=0x00 //低八位
TR1=1 //计数器开始工作
}
void time1() interrupt 3 using 1
{
TH1=0x4C
TL1=0x00
if(qiehuan == 0)
{
num++
}
}
void display(uchar hour,uchar min,uchar sec) //显示程序
{
uchar wei_1
uchar wei_2
wei_1 = hour/10 //显示小时
wei_2 = hour%10
dula=0
P0=table[wei_1]
dula=1
dula=0
wela=0
P0=0x7e
wela=1
wela=0
delay(3)
dula=0
P0=table[wei_2]
dula=1
dula=0
wela=0
P0=0x7d
wela=1
wela=0
delay(3)
wei_1 = min/10
wei_2 = min%10
dula=0
P0=table[wei_1] //显示分钟
dula=1
dula=0
wela=0
P0=0x7b
wela=1
wela=0
delay(3)
dula=0
P0=table[wei_2]
dula=1
dula=0
wela=0
P0=0x77
wela=1
wela=0
delay(3)
wei_1 = sec/10
wei_2 = sec%10
dula=0
P0=table[wei_1] //显示秒
dula=1
dula=0
wela=0
P0=0x6f
wela=1
wela=0
delay(3)
dula=0
P0=table[wei_2]
dula=1
dula=0
wela=0
P0=0x5f
wela=1
wela=0
delay(3)
}
void KeyBord(void)
{
unsigned char temp
P3=0xfe //第一行有按键按下
temp=P3
temp=temp&0xf0
if(temp!=0xf0)
{
delay10ms()
if(temp!=0xf0)
{
temp=P3
switch(temp)
{
case 0xee: //第一个键按下
qiehuan++
if(qiehuan >= 5)
{
qiehuan = 0
}
break
case 0xde: //第二个键按下
if(SETTIME == qiehuan)
{
hour++
}
if(SETCLOCK == qiehuan)
{
set_hour++
}
if(DATE == qiehuan)
{
nian++
}
if(DAOJISHI == qiehuan)
{
dao_hour++
if(dao_hour>=24)
{
dao_hour = 0
}
}
break
case 0xbe: //第三个
if(SETTIME == qiehuan)
{
min++
}
if(SETCLOCK == qiehuan)
{
set_min++
}
if(DATE == qiehuan)
{
yue++
if(yue>=13)
{
yue = 1
nian++
}
}
if(DAOJISHI == qiehuan)
{
dao_min++
if(dao_min>=60)
{
dao_min = 0
}
}
break
case 0x7e: //第四个
if(SETTIME == qiehuan)
{
sec++
}
if(SETCLOCK == qiehuan)
{
set_sec++
}
if(DATE == qiehuan)
{
ri++
if(ri>=(TIANSHU+1))
{
ri = 1
yue++
}
}
if(DAOJISHI == qiehuan)
{
dao_sec++
if(dao_sec>=60)
{
dao_sec = 0
}
}
break
}
}
}
P3=0xfd //第二行有按键按下
temp=P3
temp=temp&0xf0
if(temp!=0xf0)
{
delay10ms()
if(temp!=0xf0)
{
temp=P3
switch(temp)
{
case 0xed: //第一个键按下
djskaishi = 1
break
case 0xdd: //第二个键按下
AJflag++
if(AJflag >= 2)
{
AJflag = 0
}
break
}
}
}
}
//监测红外发射函数
void HongWai(void)
{
if(hongwai == 0)
{
delayhw()
if(hongwai == 0)
{
HWflag++
if(HWflag >= 2)
{
HWflag = 0
}
}
}
}
void ShiFenMiaoPanduan(void)
{
if(djskaishi == 0)
{
if(num==160)
{
num=0
sec++
}
if(60==sec)
{
sec = 0
min++
}
if(60==min)
{
min = 0
hour++
}
if(24==hour)
{
hour = 0
}
if(60==set_sec)
{
set_sec = 0
}
if(60==set_min)
{
set_min = 0
}
if(24==set_hour)
{
set_hour = 0
}
Hongwai()
if((hour==set_hour)&&(min==set_min))//时间是否与闹钟时间一致
{
if(HWflag==0)
{
beep = 1
}
if(HWflag == 1)
{
beep = 0 //响
}
}
else
{
beep = 1 //否,不响
}
}
if(djskaishi == 1)
{
if(num==160)
{
num=0
dao_sec--
}
if(0==sec)
{
dao_sec = 59
dao_min--
}
if(0==min)
{
dao_min = 59
dao_hour--
}
if(0==hour)
{
dao_hour = 23
}
if((0==dao_hour)&&(0==dao_min)&&(0==dao_sec))//时间是否为0
{
beep = 0 //是,蜂鸣器响
}
else
{
beep = 1 //否,不响
}
}
}
//年月日算法
void DatePanduan(void)
{
switch(yue)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: TIANSHU = 31
break
case 4:
case 6:
case 9:
case 11: TIANSHU = 30
break
case 2:
if((((nian%4)==0&&(nian%100)!=0))||(nian%100)==0&&(nian%400)==0)
{
TIANSHU = 29
}
else
{
TIANSHU = 28
}
break
}
}
void NeiRongQieHuan(void)
{
if(qiehuan == SETTIME)
{
display(hour,min,sec)
}
if(qiehuan == SETCLOCK)
{
display(set_hour,set_min,set_sec)
}
if(qiehuan == DATE)
{
display((uchar)(nian-2000), yue, ri)
}
if(qiehuan == DAOJISHI)
{
display(dao_hour,dao_min,dao_sec)
}
if(qiehuan == START)
{
display(hour,min,sec)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)