数字电子钟设计文档格式.docx
- 文档编号:20481128
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:15
- 大小:19.35KB
数字电子钟设计文档格式.docx
《数字电子钟设计文档格式.docx》由会员分享,可在线阅读,更多相关《数字电子钟设计文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
9.1源程序
#include<
reg52.h>
absacc.h>
//地址操作头文件
#defineucharunsignedchar
#defineuintunsignedint
sbitdeng=P1^7;
//LED灯的端口(模拟闹钟或者闹铃)
sbitshezhi=P1^0;
//时间设置开关
sbitjia=P1^2;
//设置时间时加1开关
sbitqiehuan=P1^1;
//年月日和时分秒切换开关
sbitjian=P1^3;
//设置时间时减1开关
ucharduan1,duan2,duan3,duan4,duan5,duan6;
//定义段选相关变量
uintmiao=00,fen=20,shi=10,nian=17,yue=1,ri=10;
//年月日、时分秒标志变量
uintt0flag=0;
//闹钟时间标志位
uchartimer[3]={10,20,50};
//闹钟的初始化时间
#defineweiXBYTE[0xff20]//PA口地址
#defineduanXBYTE[0xff21]//PB口地址
#definecontrolXBYTE[0xff23]//控制寄存器地址
ucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,};
//数码管编码表0123456789
/*---------------------定时器初始化子程序-----------------------------*/
voidtimer_init(void)
{
TMOD=0x11;
//定时/计数器0和1使用模式1,16位定时器
TH0=0x00;
//给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
TL0=0x00;
TH1=0x00;
TL1=0x00;
EA=1;
//总中断打开
ET0=1;
ET1=1;
EX0=1;
IT0=1;
}
/*------------------------------延时子程序--------------------------------*/
voiddelayms(unsignedcharms)
{
uchari;
while(--ms!
=0)
for(i=0;
i<
50;
i++);
}
/*-----------------------------显示子程序--------------------------------*/
voidxianshi()
wei=0xdf;
//打开位选,选第一位数码管11011111
duan=duan1;
//打开段选,显示数码关管第一位
delayms(3);
wei=0xef;
//打开位选,选第二位数码管11101111
duan=duan2;
//打开段选,显示数码关管第二位
wei=0xf7;
//打开位选,选第三位数码管//11110111
duan=duan3;
//打开段选,显示数码关管第三位
wei=0xfb;
//打开位选,选第四位数码管//11111011
duan=duan4;
//打开段选,显示数码关管第四位
wei=0xfd;
//打开位选,选第五位数码管11111101
duan=duan5;
//打开段选,显示数码关管第五位
wei=0xfe;
//打开位选,选第六位数码管11111110
duan=duan6;
//打开段选,显示数码关管第六位
/*------------------------------初始化子程序------------------------------*/
voidinit_all()
shezhi=1;
//引脚置高电平作为输入,四个开关都设为高电平,从给定初值开始运行
jia=1;
qiehuan=1;
jian=1;
timer_init();
control=0x80;
/*--------------------------主程序-------------------*/
voidmain()
uintflag=0,j=0,xuanze1=0,xuanze2=0;
//定义闪烁标志变量flag,闪烁时间变量j,时分
//秒选择变量xuanze1,年月日选择变量xuanze2
init_all();
while
(1)//死循环
{
if(qiehuan==1)//如果P1.1为高电平则执行以下显示和调整时间指令
xuanze2=0;
//日期设置年月日选择变量置0,防止日期时间来回切换时发生错误
if(xuanze1==0)
{
TR1=1;
//如果时间设置时分秒选择变量为0,说明处于//运行状态,此时定时器开启
flag=1;
//烁标志位强制置1,不闪烁
if((shi==timer[0])&
&
(fen==timer[1])&
(miao==timer[2]))//如果时间达到//预设值,则闹钟响(LED灯亮)
{
deng=0;
//灯亮
TR0=1;
//开始计时
}
if((fen==0)&
(miao==0))//如果是整点
//灯亮,整点提醒
delayms
(2);
deng=1;
//灯灭,关闭闹铃
}
if(!
shezhi)//P1.0设置按钮
xianshi();
//延时去抖,用显示子程序延时,防止按动按钮时闪烁
if(!
shezhi)//再次确认按键是否按下,没有按下则退出
{
while(!
shezhi)xianshi();
//如果确认按下按键等待按键释放,没有
//释放则一直执行数码管扫描,防止闪烁
TR1=0;
xuanze1++;
//确定要设定的时或分或秒
if(xuanze1==4)
xuanze1=0;
}
jia)
//延时去抖,用显示子程序延时,防止按动按钮时闪烁
if(!
jia)//再次确认按键是否按下,没有按下则退出
while(!
jia)xianshi();
//如果确认按下按键等待按键释放,没有释//放则一直执行数码管扫描,防止闪烁
{
if(xuanze1==1)//时加
shi++;
if(shi==24)
shi=0;
if(xuanze1==2)//分加
fen++;
if(fen==60)
fen=0;
if(xuanze1==3)//秒加
miao++;
if(miao==60)
miao=0;
}
if(!
jian)
jian)//再次确认按键是否按下,没有按下则退出
jian)xianshi();
//如果确认按下按键等待按键释放,没
//有释放则一直执行数码管扫描,防止闪烁
if(xuanze1==1)//时减
shi--;
if(shi==-1)
shi=23;
if(xuanze1==2)//分减
fen--;
if(fen==-1)
fen=59;
if(xuanze1==3)//秒减
miao--;
if(miao==-1)
miao=59;
if(flag==1)//闪烁标志位为1,所有数码管都亮,//与下面的flag=0构成闪烁程序
if(shi<
10)//灭零判断,如果小时数小于10则第//一位数码管熄灭
duan1=0xff;
else
duan1=table[shi/10];
//分解显示信息
duan2=table[shi%10];
duan3=table[fen/10];
duan4=table[fen%10];
duan5=table[miao/10];
duan6=table[miao%10];
if(flag==0)//闪烁标志位为0,对应数码管熄灭
if(xuanze1==1)
//当设置小时时,第一二位数码管闪烁
duan2=0xff;
if(xuanze1==2)
duan3=0xff;
duan4=0xff;
if(xuanze1==3)
duan5=0xff;
duan6=0xff;
}
}
if(qiehuan==0)//如果P1.1为低电平则执行以下显示和调整日期指令
xuanze1=0;
//时间设置时分秒选择变量置0,防止日期时间来回切换时发生错误
if(xuanze2==0)
flag=1;
shezhi)
xianshi();
if(!
{
xuanze2++;
//确定要设定的年或月或日
if(xuanze2==4)
xuanze2=0;
//延时去抖,用显示子程序延时,防止按
//动按钮时闪烁
if(!
jia)//再次确认按键是否按下,没有按下则退出
if(xuanze2==1)//年加
nian++;
if(nian==100)
nian=0;
if(xuanze2==2)//月加
yue++;
if(yue==13)
yue=1;
if(xuanze2==3)//日加
ri++;
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)//月份判断
{
if(ri==32)
ri=1;
}
if(yue==4||yue==6||yue==9||yue==11)
if(ri==31)
}
if(yue==2)
if(ri==29)
ri=1;
jian)
//延时去抖,用显示子程序延时防止//按动按钮时闪烁
jian)//再次确认按键是否按下,没有按下则退出
//如果确认按下按键等待按键释放,没
//有释放则一直执行数码管扫描,防止闪烁
if(xuanze2==1)//年减
nian--;
if(nian==-1)
nian=99;
if(xuanze2==2)//月减
yue--;
if(yue==0)
yue=12;
if(xuanze2==3)//日减
ri--;
if(ri==0)
ri=31;
ri=30;
if(ri==0)
ri=28;
if(flag==1)
duan1=table[nian/10];
//分解显示信息
duan2=table[nian%10];
duan3=table[yue/10];
duan4=table[yue%10];
duan5=table[ri/10];
duan6=table[ri%10];
if(flag==0)
if(xuanze2==1)
duan1=0xff;
//调整时间时,年时间值闪烁
duan2=0xff;
if(xuanze2==2)
//调整时间时,月时间值闪烁
if(xuanze2==3)
//调整时间时,日值闪烁
xianshi();
j++;
if(20==j)//延时闪烁时间
j=0;
flag=!
flag;
//闪烁标志变量
/*----------------------外部中断0中断子程序-------------------------------*/
voidint_x0()interrupt0//手动关闭闹钟
deng=1;
/*---------------------定时/计数器0中断子程序---------------------------*/
voidtimer0()interrupt1
uintt;
TH0=(65536-10851)/256;
//重新赋值11.0592M晶振计算,指令周期1.0851uS
TL0=(65536-10851)%256;
//最大值65536即60.398ms所以
t++;
//直接定时器不够用,需要用循环处理,
if(t==1000)//计数到10s后,自动关闭闹钟
{//定时10ms,然后循环1000次后输出10x1000=1000ms=10s
t=0;
/*--------------------------定时/计数器1中断子程序------------------------*/
voidtimer1(void)interrupt3
staticunsignedinti;
TH1=(65536-10851)/256;
//最大值65536即60.398ms所以
TL1=(65536-10851)%256;
//直接定时器不够用,需要用循环处理,
i++;
if(i==100)//定时10ms,然后循环100次后输出10x100=1000ms=1s
i=0;
miao++;
if(miao==60)//秒达到60s
miao=0;
;
//秒清零
fen++;
//分加1
if(fen==60)//分达到60
fen=0;
//分清零
shi++;
//时加1
if(shi==24)
shi=0;
ri++;
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
if(ri==32)//31天的月达到32,
ri=1;
//日回归到1,
yue++;
//月份加1
if(yue==4||yue==6||yue==9||yue==11)
if(ri==31)//30天的月达到31
//月份加1
if(yue==2)
if(ri==29)//默认2月为28天,此处是有一个缺陷,以为只有六个数码管,所以不能进行闰年还是平年
ri=1;
//日回归到1
yue++;
if(yue==13)//月达到13
yue=1;
//月回归到1
nian++;
//年加1
if(nian==100)//年达到100
nian=0;
//年回归到0,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字 电子钟 设计