实验原理:
参照实验二数码管的电路原理图,利用数码管的显示原理以及定时器的工作原理,结合按键的应用,编程实现数码管显示时钟,并具有时钟调节功能。
实验内容:
利用所学的单片机定时器中断知识及电路知识,通过单片机编程控制数码管显示时钟,并具有调节时钟的功能。利用定时器中断的知识,通过编程控制数码管显示时钟,显示格式为 XX—XX—XX,分别为小时、分钟、秒,并将矩阵键盘的第二行的前三个按键设置为独立按键,第一个按键控制调节时钟的小时、分钟、秒,第二个按键控制调节小时、分钟、秒的加,第三个按键控制调节小时、分钟、秒的减。
实验代码:
#include<REGX52.h>
typedef unsigned char uchar;
//共阴极段码
uchar code leddata[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
char s=56,m=59,h=23;
int n;
//延时函数
void Delay(unsigned int xms){
unsigned char i, j;
while(xms--){
i = 2;
j = 239;
do{
while (--j);
} while (--i);
}
}
void init(){
TMOD=0x01;//定时器 0 的方式 1,定时 4ms 0000 0001
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
ET0=1; //小开关
EA=1; //总开关
TR0=1; //启动定时器
}
void display(uchar hour,uchar minute,uchar second){
int i;
for(i=1;i<=8;i++){
switch(i){
case 1: P2_4=0;P2_3=0;P2_2=0;P0=leddata[second%10];break;
case 2: P2_4=0;P2_3=0;P2_2=1;P0=leddata[second/10];break;
case 3: P2_4=0;P2_3=1;P2_2=0;P0=0x40;break;//显示 —
case 4: P2_4=0;P2_3=1;P2_2=1;P0=leddata[minute%10];break;
case 5: P2_4=1;P2_3=0;P2_2=0;P0=leddata[minute/10];break;
case 6: P2_4=1;P2_3=0;P2_2=1;P0=0x40;break;//显示 —
case 7: P2_4=1;P2_3=1;P2_2=0;P0=leddata[hour%10];break;
case 8: P2_4=1;P2_3=1;P2_2=1;P0=leddata[hour/10];break;
}
Delay(1);
P0=0; //消影
}
}
void key_scan(){
static uchar flag=0;
if(P3_1==0){
Delay(20);
while(P3_1==0)
/*display(h,m,s)*/;
Delay(20);
TR0=0;//关闭中断请求
flag++;
if(flag==4){
flag=0;
TR0=1;
}
}
if(flag!=0){
switch(flag){
case 1:if(P3_0==0){ Delay(20);while(P3_0==0)display(h,m,s);Delay(20);h++; if(h>23) h=0;}break;
case 2:if(P3_0==0){ Delay(20);while(P3_0==0)display(h,m,s);Delay(20);m++; if(m>59) m=0;}break;
case 3:if(P3_0==0){ Delay(20);while(P3_0==0)display(h,m,s);Delay(20);s++; if(s>59) s=0;}break;
default:break;
}
switch(flag){
case 1:if(P3_2==0){ Delay(20);while(P3_2==0)display(h,m,s);Delay(20);h--; if(h<0) h=23;}break;
case 2:if(P3_2==0){ Delay(20);while(P3_2==0)display(h,m,s);Delay(20);m--; if(m<0) m=59;}break;
case 3:if(P3_2==0){ Delay(20);while(P3_2==0)display(h,m,s);Delay(20);s--; if(s<0) s=59;}break;
default:break;
}
}
}
void main(){
init();
while(1){
display(h,m,s);
key_scan();
}
}
//4毫秒的定时器中断
void timer0() interrupt 1
{
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
n++;
if(n==250)
{
n=0;
s++;
if(s>=60)
{
s=0;
m++;
if(m>=60)
{
m=0;
h++;
if(h>=24)
h=0;
}
}
}
}
主流程图:
仿真电路图:
开发板电路:
实验效果图:
按键K1 效果(有四个档位,按第一次时暂停,并选中“时”,按第二次选中”分“,按第三次选中”分“
,第四次按下结束暂停,继续计时)
按键K2、K3效果:(K2按下被选中的“时分秒”被加一;K3按下被选中的“时分秒”被减一)