题目:单片机电子时钟的设计
设计一个时钟,可以正常显示时分秒,也可以通过按键改变分钟和小时,且有整点提醒功能
1、能够正常计时并且能够显示小时、分钟、秒,10分。
(1)正常显示秒,2分
(2)正常显示分,2分
(3)正常显示时,2分
(4)秒进位至分正常,2分
(5)分进位至小时正常,1分
2、可以通过按键正常更改小时和分钟(4个按键都要用到),以及蜂鸣器在整点要发出响声,5分。
(1)实现分钟正常(更改过程中显示数字在0-59范围以内)加减,2分
(2)实现小时正常(更改过程中显示数字在0-23范围以内)加减,2分
(3)蜂鸣器在整点会响(提示:单片机P2.3管脚为0时,蜂鸣器会响。为1时则不响),2分
提问环节:教师提问有关电子时钟的3个问题,根据学生回答情况给分,每个问题5分,满分15分。
使用的单片机:
Notes:代码注释写的比较细,便于大家理解。如果是考察课,期末老师提问课程设计,一般会问的很简单,不会针对某一语或揪着不放的。比如会问你dispNum()那一块的代码是实现什么功能的,分钟60进位是如何实现的等等。
参考代码:
// hill20200709
#include<reg52.h> //引入头文件
#include<intrins.h> //左右移函数头文件
#define uchar unsigned char //变量声明
#define uint unsigned int //变量声明
sbit key1=P3^4; //按键key1声明
sbit key2=P3^5; //按键key2声明
sbit key3=P3^6; //按键key3声明
sbit key4=P3^7; //按键key4声明
sbit buzzer=P2^3; //蜂鸣器声明
sbit DU =P2^6; //位声明DU
sbit WE =P2^7; //位声明WE
uchar num;
uchar code table[]={ //数码管显示用的数组
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
int s=0; //声明并初始化 秒 变量
int min=0; //声明并初始化 分钟 变量
int h=0; //声明并初始化 小时 变量
void delayms(uint xms) // 延时函数 用于数码管显示
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void dispNum(int h, int min, int s){ //数码管显示函数 实现小时、分钟、秒数的显示
int m2 = min/10; //十位
int m1 = min%10; //个位
int s2 = s/10;
int s1 = s%10;
int h2 = h/10;
int h1 = h%10;
DU=1;
P0=table[h1];
DU=0;
WE=1;
P0=0xfd; //1111 1101 第2个数码管 小时个位
WE=0;
delayms(2);
DU=1;
P0=table[h2];
DU=0;
WE=1;
P0=0xfe; //1111 1110 第1个数码管 小时十位
WE=0;
delayms(2);
DU=1;
P0=table[m1];
DU=0;
WE=1;
P0=0xf7; //1111 0111 第4个数码管 分钟个位
WE=0;
delayms(2);
DU=1;
P0=table[m2];
DU=0;
WE=1;
P0=0xfb;//1111 1011 第3个数码管 分钟十位
WE=0;
delayms(2);
DU=1;
P0=table[s1];
DU=0;
WE=1;
P0=0xdf; //1101 1111 第6个数码管 秒个位
WE=0;
delayms(2);
DU=1;
P0=table[s2];
DU=0;
WE=1;
P0=0xef;//1110 1111 第5个数码管 秒十位
WE=0;
delayms(2);
}
//key函数 实现用按键对小时、分钟调整
void key(){
if (key1==0){ //adjust hour -plus 调整小时 加
delayms(10); //10ms
if (key1==0){
h++;
if(h==24){
h=0; //注意是24小时清零
}
while(!key1); //没弹起就在空循环里面,所以按下数字显示不全
}
}
if (key2==0){ //adjust hour -minus 调整小时 减
delayms(10); //10ms
if (key2==0){
h--;
if(h==-1){
h=23;
}
while(!key2); //没弹起就在空循环里面,所以按下数字显示不全
}
}
if (key3==0){ //adjust min -plus 调整分钟 加
delayms(10); //10ms
if (key3==0){
min++;
if(min==60){
min=0;
}
while(!key3); //没弹起就在空循环里面,所以按下数字显示不全
}
}
if (key4==0){ //adjust min -minus 调整分钟 减
delayms(10); //10ms
if (key4==0){
min--;
if(min==-1){
min=59;
}
while(!key4); //没弹起就在空循环里面,所以按下数字显示不全
}
}
}
void soundTime(int time){ //蜂鸣器的实现函数 参数为蜂鸣器报警的时间
buzzer=0; //蜂鸣器开
delayms(time);
buzzer=1; //蜂鸣器关
}
void main()
{
TMOD=0x01; //TMOD的值表示定时器工作方式选择
TH0=(65536-45872)/256; //数装入TH0寄存器
TL0=(65536-45872)%256; //数装入TL0寄存器
EA=1; //开总中断
ET0=1; //允许定时器0中断
TR0=1; //开始计数
while(1) //下面是个死循环,为了让程序不停地执行
{
dispNum(h,min,s); //显示函数
key(); //
if(num==20) //循环20次为一秒
{
num=0;
s++; //秒加一
//soundTime(10);
//在此调用检查函数soundTime() 若蜂鸣器每一秒都响 则函数正常
if(s==60){ //秒到60进位
s=0;
min++; //秒清零 分钟加一
if(min==60){ //分钟到60进位
min=0;
h++; //分钟清零 小时加一
soundTime(500); //buzzer 蜂鸣器在分钟从59到清零的时候 整点报时
if(h==24){
h=0; //小时满24清零
}
}
}
}
}
}
void T0_time() interrupt 1 //中断函数
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
num++;
}
才疏学浅,多多关照!文章内容肯定有不当之处,敬请指出改正。