11.基于定时器的时钟程序设计

第零讲 基于定时器的时钟程序设计

时钟程序设计

数码管小数点

1000 0000(0x80)为点亮小数点

例:0x5b为显示2,0x5b|0x80为点亮小数点

Seg.c

#include <Seg.h>

//数码管显示函数
unsigned char Seg_Dula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//段码储存数组
unsigned char Seg_Wela[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位码储存数组

unsigned char Seg_Disp(unsigned char wela,dula,point)
{
	P0=0x00;
	P2_6=1;
	P2_6=0;
	
	P0=Seg_Wela[wela];
	P2_7=1;
	P2_7=0;
	
	if(point==1)
		P0=Seg_Dula[dula]|0x80;
	else
		P0=Seg_Dula[dula];
	P2_6=1;
	P2_6=0;
}

Seg.h

#include <REGX52.H>

unsigned char Seg_Disp(unsigned char wela,dula,point);

Key.c

#include <Key.h>

unsigned char Key_Read()
{
	unsigned char temp=0;
	P3_0=0;P3_1=1;P3_2=1;P3_3=1;
	if(P3_4==0)temp=1;
	if(P3_5==0)temp=2;
	if(P3_6==0)temp=3;
	if(P3_7==0)temp=4;
	P3_0=1;P3_1=0;P3_2=1;P3_3=1;
	if(P3_4==0)temp=5;
	if(P3_5==0)temp=6;
	if(P3_6==0)temp=7;
	if(P3_7==0)temp=8;
	P3_0=1;P3_1=1;P3_2=0;P3_3=1;
	if(P3_4==0)temp=9;
	if(P3_5==0)temp=10;
	if(P3_6==0)temp=11;
	if(P3_7==0)temp=12;
	P3_0=1;P3_1=1;P3_2=1;P3_3=0;
	if(P3_4==0)temp=13;
	if(P3_5==0)temp=14;
	if(P3_6==0)temp=15;
	if(P3_7==0)temp=16;
	
	return temp;
}

Key.h

#include <REGX52.H>

unsigned char Key_Read();

main

#include <REGX52.H>
#include <Key.h>
#include <Seg.h>

unsigned char Key_Slow_Down;
unsigned int Seg_Slow_Down;
unsigned char Key_Val,Key_Old,Key_Up,Key_Down;
unsigned char Seg_Buf[6]={10,10,10,10,10,10};
unsigned char Seg_Pos;
unsigned char Seg_Disp_Mode;//0-时钟显示 1-时钟设置 2-闹钟设置
unsigned char Clock_Disp[3]={23,59,55};
unsigned int Timer_1000ms;//计时专用变量
unsigned char Seg_Point[6]={0,1,0,1,0,1};
unsigned char Clock_Set[3];
unsigned char Clock_Set_Index;//0-小时 1-分钟 2-秒钟
unsigned int Timer_500ms;
bit Seg_Flag;
unsigned char Alarm[]={0,0,0};
unsigned char Alarm_Set[3];
bit Alarm_Flag=1;
unsigned char Led;
bit Alarm_Enable_Flag;

void Key_Proc()
{
	if(Key_Slow_Down)return;
	Key_Slow_Down=1;
	
	Key_Val=Key_Read();
	Key_Down=Key_Val&(Key_Old^Key_Val);
	Key_Up=~Key_Val&(Key_Old^Key_Val);
	Key_Old=Key_Val;
	
	if(Key_Down !=0)
		Alarm_Enable_Flag=0;
	switch(Key_Down)
	{
		case 1:
			Clock_Set_Index=0;
			Clock_Set[0]=Clock_Disp[0];
			Clock_Set[1]=Clock_Disp[1];
			Clock_Set[2]=Clock_Disp[2];
			Seg_Disp_Mode=1;
		break;
		case 2:
			Clock_Set_Index=0;//复位
			Alarm_Set[0]=Alarm[0];
			Alarm_Set[1]=Alarm[1];
			Alarm_Set[2]=Alarm[2];
			Seg_Disp_Mode=2;
		break;
		case 3:
			Clock_Set_Index++;
			if(Clock_Set_Index ==3)
				Clock_Set_Index=0;
		break;
		case 4:
			Alarm_Flag ^= 1;	
		break;
		case 5:
			if(Seg_Disp_Mode ==1)
			{
				Clock_Set[Clock_Set_Index]++;
				//指针指0上限24,不指0上限60
				if(Clock_Set[Clock_Set_Index] == (Clock_Set_Index==0?24:60))
					Clock_Set[Clock_Set_Index]=0;
			}
			if(Seg_Disp_Mode ==2)
			{
				Alarm_Set[Clock_Set_Index]++;
				//指针指0上限24,不指0上限60
				if(Alarm_Set[Clock_Set_Index] == (Clock_Set_Index==0?24:60))
					Alarm_Set[Clock_Set_Index]=0;
			}
		break;
		case 6:
			if(Seg_Disp_Mode ==1)
			{
				Clock_Set[Clock_Set_Index]--;
				if(Clock_Set[Clock_Set_Index] == 255)
					Clock_Set[Clock_Set_Index]=Clock_Set_Index==0?23:59;
			}
			if(Seg_Disp_Mode ==2)
			{
				Alarm_Set[Clock_Set_Index]--;
				if(Alarm_Set[Clock_Set_Index] == 255)
					Alarm_Set[Clock_Set_Index]=Clock_Set_Index==0?23:59;
			}
		break;
		case 7:
			if(Seg_Disp_Mode ==1)
			{
				Clock_Disp[0]=Clock_Set[0];
				Clock_Disp[1]=Clock_Set[1];
				Clock_Disp[2]=Clock_Set[2];
			}
			if(Seg_Disp_Mode ==2)
			{
				Alarm[0]=Alarm_Set[0];
				Alarm[1]=Alarm_Set[1];
				Alarm[2]=Alarm_Set[2];
			}
			Seg_Disp_Mode =0;
		break;
		case 8:
			Seg_Disp_Mode =0;
		break;
	}
}

void Seg_Proc()
{
	unsigned char i;
	if(Seg_Slow_Down)return;
	Seg_Slow_Down=1;
	
	switch(Seg_Disp_Mode)
	{
		case 0:
			/*
			Seg_Buf[0]=Clock_Disp[0]/10;
			Seg_Buf[1]=Clock_Disp[0]%10;
			Seg_Buf[2]=Clock_Disp[1]/10;
			Seg_Buf[3]=Clock_Disp[1]%10;
			Seg_Buf[4]=Clock_Disp[2]/10;
			Seg_Buf[5]=Clock_Disp[2]%10;
			*/
			for(i=0;i<3;i++)
			{
				Seg_Buf[0+2*i]=Clock_Disp[i]/10;
				Seg_Buf[1+2*i]=Clock_Disp[i]%10;
			}
		break;
		case 1:
			Seg_Buf[0]=Clock_Set[0]/10;
			Seg_Buf[1]=Clock_Set[0]%10;
			Seg_Buf[2]=Clock_Set[1]/10;
			Seg_Buf[3]=Clock_Set[1]%10;
			Seg_Buf[4]=Clock_Set[2]/10;
			Seg_Buf[5]=Clock_Set[2]%10;
		
			switch(Clock_Set_Index)
			{
				case 0:
					Seg_Buf[0]=Seg_Flag?Clock_Set[0]/10:10;//为真则显示,为假熄灭
					Seg_Buf[1]=Seg_Flag?Clock_Set[0]%10:10;
				break;
				case 1:
					Seg_Buf[2]=Seg_Flag?Clock_Set[1]/10:10;
					Seg_Buf[3]=Seg_Flag?Clock_Set[1]%10:10;
				break;
				case 2:
					Seg_Buf[4]=Seg_Flag?Clock_Set[2]/10:10;
					Seg_Buf[5]=Seg_Flag?Clock_Set[2]%10:10;
				break;
			}
			//Seg_Buf[0+Clock_Set_Index*2]=Seg_Flag?Clock_Set[Clock_Set_Index]/10%10:10;
			//Seg_Buf[1+Clock_Set_Index*2]=Seg_Flag?Clock_Set[Clock_Set_Index]%10:10;
		break;
		case 2:
			Seg_Buf[0]=Alarm_Set[0]/10;
			Seg_Buf[1]=Alarm_Set[0]%10;
			Seg_Buf[2]=Alarm_Set[1]/10;
			Seg_Buf[3]=Alarm_Set[1]%10;
			Seg_Buf[4]=Alarm_Set[2]/10;
			Seg_Buf[5]=Alarm_Set[2]%10;
			Seg_Buf[0+Clock_Set_Index*2]=Seg_Flag?Alarm_Set[Clock_Set_Index]/10%10:10;
			Seg_Buf[1+Clock_Set_Index*2]=Seg_Flag?Alarm_Set[Clock_Set_Index]%10:10;
		break;
					
	}
}

void Led_Proc()
{
	if(Alarm_Flag ==1)
	{
		if(Clock_Disp[0]==Alarm[0] && Clock_Disp[1]==Alarm[1] && Clock_Disp[2]==Alarm[2])
			Alarm_Enable_Flag=1;
		if(Alarm_Enable_Flag==1)
		{
			P2_3=0;//蜂鸣器响
			P1 = Led;
		}
		else
		{
			P2_3=1;
			P1=0xff;
		}
	}
	else
		{
			P2_3=1;
			P1=0xff;
		}
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;
	EA = 1;
}

void Timer0Server() interrupt 1
{
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	if(++Key_Slow_Down ==10) Key_Slow_Down=0;
	if(++Seg_Slow_Down ==500) Seg_Slow_Down=0;
	if(++Seg_Pos==6)Seg_Pos=0;
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Timer_1000ms++;
	if(Timer_1000ms == 1000)
	{
		Timer_1000ms=0;
		Clock_Disp[2]++;
		if(Clock_Disp[2]==60)
		{
			Clock_Disp[2]=0;
			Clock_Disp[1]++;
			if(Clock_Disp[1]==60)
			{
				Clock_Disp[1]=0;
				Clock_Disp[0]++;
				if(Clock_Disp[0]==24)
					Clock_Disp[0]=0;
			}
		}
	}
	Timer_500ms++;
	if(Timer_500ms ==500)
	{
		Timer_500ms=0;
		Seg_Flag ^= 1;
		if(Clock_Disp[0] >= 12)
			Led ^=0xf0;//1111 0000
		else
			Led ^=0x0f;//0000 1111
	}
}

void main()
{
	Timer0_Init();
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}