单片机做闹钟程序中,如何用定时器中断计时一个时间,闹钟时间到时就响,比如一分钟后就停止响。

单片机做闹钟程序中,如何用定时器中断计时一个时间,闹钟时间到时就响,比如一分钟后就停止响。,第1张

1设置变量

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)

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12448721.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存