/******************************************************************************
功能:
本程序在12M晶振模式下,通过定时器中断精确实现数字时钟计时 *** 作,并在KEIL
中实现输出。时、分、秒的变化在定时中断里处理。
说明:
因采用工作方式2,自动装入初值,所以此程序计时很精确,只是在KEIL中模拟输
出显示的变化速度很快,这点可不理会
******************************************************************************/
#include
#include
#define
TEST
//此行用于KEIL输出显示,如果不需要显示可将其删除
typedef
unsigned
char
uchar
typedef
unsigned
int
uint
#define
TH0TL0_INIT
(256-250)
//定时器8位自动装入模式下寄存器初值,0.25ms中断一次
char
cHour
//时
char
cMin
//分
char
cSec
//秒
uint
iCount
//秒计数,计数达到4000时1s,4000*0.25ms
=1000ms
=
1s
bit
bSecChanged
//秒发生变化标志,每秒送一次输出显示,送显完成后清0,提高主程序效率
//==============================================================================
//T0定时器中断服务程序,12M晶振下每0.25ms产生中断,本程序执行一次
//==============================================================================
void
Timer0()
interrupt
1
{
iCount++
//秒计数值+1
if(iCount==4000)
{//时间计数达到1S
iCount
=
0
//重新开始下一秒计数
cSec++
//时钟:秒+1
bSecChanged
=
1
//置秒发生变化标志
if(cSec==60)
{//计够60s
cSec
=
0
//重新开始下一分计数
cMin++
//时钟:分+1
}
if(cMin==60)
{//计够60分钟
cMin
=
0
//重新开始下一小时计数
cHour++
//时钟:小时+1
}
if(cHour==24)
{//计够24小时
cHour
=
0
//重新开始第二天计数
}
}
}
//==============================================================================
//主程序
//==============================================================================
void
main()
{
uchar
outstr[10]
//输出字符串,我的编译器可能有问题,直接输出有错
TMOD
=
0X02//工作方式2,8位自动重装计时模式
TH0
=
TH0TL0_INIT
//0.25ms中断一次
TL0
=
TH0TL0_INIT
//0.25ms中断一次
#ifdef
TEST
SCON
=
0x50
/*
SCON:
mode
1,
8-bit
UART,
enable
rcvr
*/
TMOD
|=
0x20
/*
TMOD:
timer
1,
mode
2,
8-bit
reload
*/
TH1
=
221
/*
TH1:
reload
value
for
1200
baud
@
16MHz
*/
TR1
=
1
/*
TR1:
timer
1
run
*/
TI
=
1
/*
TI:
set
TI
to
send
first
char
of
UART
*/
#endif
cHour
=
0
//时
cMin
=
0
//分
cSec
=
0
//秒
iCount
=
0
//秒计数
bSecChanged
=
0
outstr[2]
=
':'
//时分分隔符
outstr[5]
=
':'
//分秒分隔符
outstr[8]
=
0
//字符串结束符
EA=1
//开总中断
ET0=1
//允许T0中断
TR0=1
//启动T0
while(1)
{
if(bSecChanged==1)
{//秒发生变化,将时间值转换为可显示字符串准备送显示
bSecChanged
=
0//清除标志,节省CPU资源
outstr[0]
=
cHour/10
+
0x30
//将秒转换为ASCII码
outstr[1]
=
cHour%10
+
0x30
outstr[3]
=
cMin/10
+
0x30
//将分转换为ASCII码
outstr[4]
=
cMin%10
+
0x30
outstr[6]
=
cSec/10
+
0x30
//将小时转换为ASCII码
outstr[7]
=
cSec%10
+
0x30
#ifdef
TEST
printf("
%s\r",outstr)
//在KEIL中显示时钟
#endif
}
}
}
#include<reg51.h>#define uchar unsigned char
uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}//0-9
uchar scanled
uchar flag=0
uchar disdat[6]
void delay(unsigned int x)
{
unsigned int i,j
for(i=0i<xi++)
for(j=0j<120j++)
}
void dischg()
{
uchar i
for(i=0i<6i++)
disdat[i]=10
}
void ext0() interrupt 0
{
flag=1
}
void ext1() interrupt 2
{
flag=2
}
void t1isr() interrupt 3 //显示
{
TH1=0xec
TL1=0x78
switch(scanled)
{
case 0:
P2=0x01
P0=~ledtab[disdat[5]]
break
case 1:
P2=0x02
P0=~ledtab[disdat[4]]
break
case 2:
P2=0x04
P0=~ledtab[disdat[3]]
break
case 3:
P2=0x08
P0=~ledtab[disdat[2]]
break
case 4:
P2=0x10
P0=~ledtab[disdat[1]]
break
case 5:
P2=0x20
P0=~ledtab[disdat[0]]
break
default:break
}
scanled++
scanled%=6
}
main()
{
uchar i,j
TMOD=0x10
TH1=0xec
TL1=0x78
TR1=1
ET1=1
IT0=1
IT1=1
EX0=1
EX1=1
EA=1
scanled=0
dischg()
while(1)
{
i=0
switch(flag)
{
case 1:
for(j=0j<3j++)
for(i=0i<10i++)
{
disdat[5]=disdat[4]
disdat[4]=disdat[3]
disdat[3]=disdat[2]
disdat[2]=disdat[1]
disdat[1]=disdat[0]
disdat[0]=i
delay(200)
}
dischg()
flag=0
break
case 2:
for(j=0j<3j++)
for(i=0i<10i++)
{
disdat[0]=disdat[1]
disdat[1]=disdat[2]
disdat[2]=disdat[3]
disdat[3]=disdat[4]
disdat[4]=disdat[5]
disdat[5]=i
delay(200)
}
dischg()
flag=0
break
default:break
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)