按键调节时钟的应用实验

一、实验目的
(一)进一步掌握数码管的显示控制;
(二)进一步掌握单片机的定时器中断的应用;
(三)进一步掌握定时器工作方式的控制及各种寄存器的应用;
(四)掌握独立按键的使用方法。
二、主要仪器设备及耗材:
(一)电脑一台;
(二)单片机开发板一套。
三、实验原理
参照实验二数码管的电路原理图,利用数码管的显示原理以及定时器的工作原理,结合按键的应用,编程实现数码管显示时钟,并具有时钟调节功能。

四、实验内容及步骤
(一)实验内容利用所学的单片机定时器中断知识及电路知识,通过单片机编程控制数码管显示时钟,并具有调节时钟的功能。利用定时器中断的知识,通过编程控制数码管显示时钟,显示格式为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();
	}
}


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐