第零讲 基于定时器的时钟程序设计
时钟程序设计
数码管小数点
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();
}
}
