单片机:按键调节时钟
按键调节时钟的应用实验一、实验目的(一)进一步掌握数码管的显示控制;(二)进一步掌握单片机的定时器中断的应用;(三)进一步掌握定时器工作方式的控制及各种寄存器的应用;(四)掌握独立按键的使用方法。二、主要仪器设备及耗材:(一)电脑一台;(二)单片机开发板一套。三、实验原理参照实验二数码管的电路原理图,利用数码管的显示原理以及定时器的工作原理,结合按键的应用,编程实现数码管显示时钟,并具有时钟调节功
按键调节时钟的应用实验
一、实验目的
(一)进一步掌握数码管的显示控制;
(二)进一步掌握单片机的定时器中断的应用;
(三)进一步掌握定时器工作方式的控制及各种寄存器的应用;
(四)掌握独立按键的使用方法。
二、主要仪器设备及耗材:
(一)电脑一台;
(二)单片机开发板一套。
三、实验原理
参照实验二数码管的电路原理图,利用数码管的显示原理以及定时器的工作原理,结合按键的应用,编程实现数码管显示时钟,并具有时钟调节功能。
四、实验内容及步骤
(一)实验内容利用所学的单片机定时器中断知识及电路知识,通过单片机编程控制数码管显示时钟,并具有调节时钟的功能。利用定时器中断的知识,通过编程控制数码管显示时钟,显示格式为XX—XX—XX,分别为小时、分钟、秒,并将矩阵键盘的第二行的前三个按键设置为独立按键,第一个按键控制调节时钟的小时、分钟、秒,第二个按键控制调节小时、分钟、秒的加,第三个按键控制调节小时、分钟、秒的减。
五. 工作原理
(一)80C51中断系统
80C51的中断系统有5个中断源(8052有6个),2个优先级,可实现二级中断嵌套。
80C51中断系统的结构如图5.1所示。
(二)定时/计数器的结构和工作原理
1.定时/计数器的结构定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。定时/计数器的结构如图5.2所示。
2.定时/计数器的工作原理
加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟振荡器输出脉冲经12分频后送来;一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。
(三)定时/计数器的控制
80C51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
1.工作方式寄存器TMOD工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如图5.3所示。
2.控制寄存器TCONTCON的低4位用于控制外部中断,已在前面介绍。TCON的高4位用于控制定时/计数器的启动和中断申请。其格式如图5.4所示。
实现代码如下:
#include <reg51.h>
#define smg_1 c=1;b=1;a=1 //选中第一个数码管
#define smg_2 c=1;b=1;a=0
#define smg_3 c=1;b=0;a=1
#define smg_4 c=1;b=0;a=0
#define smg_5 c=0;b=1;a=1
#define smg_6 c=0;b=1;a=0
#define smg_7 c=0;b=0;a=1
#define smg_8 c=0;b=0;a=0
sbit k1=P3^1;//独立按键1
sbit k2=P3^0;
sbit k3=P3^2;
sbit a=P2^2;//引脚位声明,用于选中数码管
sbit b=P2^3;
sbit c=P2^4;
int t=0,count=0,h=11,m=1,s=50;//h,m,s可以初始化时间,此时的时间表示:11:01:50
char code number[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//用于数码管显示0-9
void delay(unsigned int ms)
{
char i;
while(ms--)
for(i=0; i<110; i++);
}
void init()
{
//补充:51单片机有2个定时器,0和1,TH0、TL0和ET0是管定时器0,
//TH1、TL1和ET1是管定时器1,要用那个定时器就要用相应参数设置
//我们这里使用的是定时器0,工作方式0,定时间隔5ms
TMOD = 0x00; //选用工作方式0
TH0 = (8192-5000)/32; //设置高8位, 8192=2^13; 5000表示计时间隔为5ms
TL0 = (8192-5000)%32; //设置低5位
EA=1; //EA标志位置1,允许所有中断,相当于打开总开关
ET0=1; //ET0标志位置1,打开定时器0的中断开关,相当于打开支线开关 T0
TR0=1; //开启TR0计数,即开启定时器0计数
}
void time0() interrupt 1
{
TH0 = (8192-5000)/32;
TL0 = (8192-5000)%32;
//计时到达5ms时,即高8位和低五位时,计数器溢出,自动向CPU发送溢出中断请求
t++; //hh-mm-ss
if(t==200) //5ms*200=1s
{
t=0;
s++;
if(s==60)
{
s=0;
m++;
if(m==60)
{
m=0;
h++;
if(h==24)
{
h=0;
}
}
}
}
}
void display()
{
smg_1;
P0 = number[h/10];//h
delay(1);
smg_2;
P0 = number[h%10];//h
delay(1);
smg_3;
P0 = 0x40; //-
delay(1);
smg_4;
P0 = number[m/10];//m
delay(1);
smg_5;
P0 = number[m%10];//m
delay(1);
smg_6;
P0 = 0x40;//-
delay(1);
smg_7;
P0 = number[s/10];//s
delay(1);
smg_8;
P0 = number[s%10];//s
delay(1);
}
void keyDown()
{
if(!k1)//第一个键按下时
{
delay(10);
if(!k1)
{
TR0=0;
count++;
while(!k1); //
if(count==4)
{
TR0=1;
count=0;
}
}
}
if(!k2)//第二个键按下时
{
while(!k2);//第二个键按下后松手时,跳出该循环
if(count==1)
{
h++;
if(h==24) h=0;
}
if(count==2)
{
m++;
if(m==60) m=0;
}
if(count==3)
{
s++;
if(s==60) s=0;
}
}
if(!k3)//第三个键按下时
{
while(!k3);//第三个键按下后松手时,跳出该循环
if(count==1)
{
h--;
if(h==-1) h=23;
}
if(count==2)
{
m--;
if(m==-1) m=59;
}
if(count==3)
{
s--;
if(s==-1) s=59;
}
}
}
void main()
{
init();//初始化工作
while(1)
{
display();
keyDown();
}
}
更多推荐
所有评论(0)