电子信息工程专业课程设计题目及要求基于MCS-51单片机的电子钟应用背景:利用单片机的定时器实现电子钟功能,要求在6位数码管上分别显示时、分、秒功能。另外设置两个按键K1、K2,当按下K1时,可以进入调整小时、分钟模式或者正常运行模式。在调整模式下,利用K2调整小时、分钟。在调整模式下,显示小时、分钟的数码管处于相应的闪烁状态。另外,加蜂鸣器,当整点时,让蜂鸣器鸣笛(鸣笛的次数与小时数相同);半点时,仅鸣笛一声。设计要求:使用Proteus和Keil软件,设计电路并编写程序,通过联合仿真实现如下功能: 功能1. 正常模式下,6位数码管能够正常显示时、分、秒,且能按照时间正常计时。在调整模式下,数码管停止计时,调“小时”和“分钟”时,对应的两位数码管处于闪烁状态。功能2. 按下按键1时,分别可以进入正常模式、调整小时模式、调整分钟模式。功能3. 在正常模式下,按下按键2时,无操作; 调整小时模式、调整分钟模式下,按下按键2时,小时+1或者分钟+1。功能4. 蜂鸣器可以实现整点、半点报时功能。
/*在本次实验中,key1/key2按键由于本身程序扫描时间,以及led闪烁时间,按键不够灵敏,也就是说当按下按键,而程序在执行其他程序时,可能有严延迟,解决方法为修改延时函数的延时市时长*/
#include<reg51.h>
sbit P36=P3^6;
sbit P35=P3^5;
sbit beep=P3^7;
unsigned int key1;
unsigned char sec,min,hour;
unsigned char num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};/*采用共阴极的动态显示方法*/
void delay(unsigned int p)
{
unsigned int j,k;
for(j=0;j<p;j++)
{ for(k=0;k<100;k++); }
}/*设置可以修改参数的延时函数,来实现动态显示与闪烁显示*/
void dis_sec(unsigned int u)
{P2=0xdf;P0=num[sec%10];delay(u); P2=0xef;P0=num[sec/10];delay(u);}
void dis_min(unsigned int x)
{ P2=0xf7;P0=num[min%10]|0x80;delay(x); P2=0xfb;P0=num[min/10];delay(x);}
void dis_hour(unsigned int y)
{P2=0xfd;P0=num[hour%10]|0x80;delay(y); P2=0xfe;P0=num[hour/10];delay(y);}/*设置秒、分、时的各种显示函数,带参便于实现动态显示与闪烁显示两种情况*/
void int_start()
{
TMOD=0x61;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TL1=256-1;
TH1=256-1;
ET0=1;ET1=1;
TR0=1;TR1=1;
EA=1;
}
void buzzer()
{ unsigned char i;
if(hour!=0)
{if(sec+min==0)
{for(i=0;i<hour;i++){beep=0;delay(1000);beep=1;delay(1000);}}
}
if(min==30)
{if(sec==0)
{beep=0;delay(250);beep=1;}}
}
void timer0(void) interrupt 1 using 1
{ unsigned char a;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
a++;
if(a>=20)
{sec++;a=0;}
if(sec>=60)
{min++;sec=0;}
if(min>=60)
{hour++;min=0;}
if(hour>=24)
{hour=0;min=0;sec=0;}
}/*设置时、分、秒的数值,采用24小时制*/
void scan_key2(unsigned int t)
{ if(P36==0)
{
if(t==1)
if(hour<=24){hour++;}else{hour=0;}
if(t==2)
if(min<=60){min++;}else{min=0;hour++;}
}
}/*带参是为了便于各自调整时钟还是分钟*/
void counter1(void) interrupt 3 using 2
{
key1++;
if(key1==1){TR0=0;delay(500);while(P35){scan_key2(1);dis_hour(250);}}
if(key1==2){delay(500);while(P35){scan_key2(2);dis_min(250);}}
if(key1==3){delay(500);TR0=1;key1=0;}
}
/*对于key1的处理采用计数器中断,每按下一次跳转到该中断函数,key1值为0、1、2,大于2的记为0,为0正常工作,为1时钟闪烁显示,为2分钟闪烁显示,然后在通过key2进行数值调整*/
void main()
{
int_start();
while(1)
{ dis_sec(1);dis_min(1);dis_hour(1);buzzer(); }
}/*主函数当buzzer不工作时不影响动态显示*/