10.基于定时器的倒计时程序设计

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

模块化代码

Key.c

独立键盘

unsigned char Key_Read()
{
	unsigned char temp=0;
	if(P3_4 ==0) temp=1;
	if(P3_5 ==0) temp=2;
	if(P3_6 ==0) temp=3;
	if(P3_7 ==0) temp=4;
	return temp;
}

矩阵键盘

#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();

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};//位码储存数组

void Seg_Disp(unsigned char wela,dula)
{
	P0=0x00;
	P2_6=1;
	P2_6=0;
	
	P0=Seg_Wela[wela];
	P2_7=1;
	P2_7=0;
	
	P0=Seg_Dula[dula];
	P2_6=1;
	P2_6=0;
	
}

Seg.h

#include <REGX52.H>

void Seg_Disp(unsigned char wela,dula);

main

1.头文件

2.变量声明

3.Key_Proc()

4.Seg_Proc()

5.Led_Prco()

6.Timer0Init()

7.Server

8.main

#include <REGX52.H>
#include <Key.h>
#include <Seg.h>
 
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Seg_Slow_Down;//数码管减速专用变量 500ms
unsigned char Key_Down,Key_Old,Key_Up,Key_Val;//按键扫描专用变量
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6]={1,2,3,4,5,6};//数码管显示数据存放数组

//按键处理函数
void Key_Proc()
{
	if(Key_Slow_Down)return;
	Key_Slow_Down=1;//按键减速程序
	
	Key_Val=Key_Read();//读取按下的键码值
	Key_Down=Key_Val&(Key_Val^Key_Old);//捕捉下降沿
	//Key_Up=~Key_Val&(Key_Val^Key_Old);
	Key_Old=Key_Val;//辅助扫描
	
	switch(Key_Down)
	{
		
	}
}

//信息处理函数
void Seg_Proc()
{
	if(Seg_Slow_Down)return;
	Seg_Slow_Down=1;//数码管减速程序
	
	
}

//其他显示函数
void Led_Proc()
{
	
}

//定时器0初始化函数
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;
}

//定时器0中断服务函数
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]);
}

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

蜂鸣器


P2_3=0;//响
P2_3=1;//不响

倒计时程序设计

#include <REGX52.H>
#include <Key.h>
#include <Seg.h>
 
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Seg_Slow_Down;//数码管减速专用变量 500ms
unsigned char Key_Down,Key_Old,Key_Up,Key_Val;//按键扫描专用变量
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6]={10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Mode;//数码管显示界面 0-显示 1-设置
unsigned int Timer_1000ms;//1000ms标志位
unsigned char Time_Count=30;//系统计时变量
bit System_Flag;//系统标志位 0-暂停 1-开始
unsigned char Set_Dat[3]={15,30,60};//设置参数储存数组
unsigned char Set_Dat_Index=1;
unsigned int Timer_500ms;//500ms标志位
bit Seg_Flag;//数码管标志位

//按键处理函数
void Key_Proc()
{
	if(Key_Slow_Down)return;
	Key_Slow_Down=1;//按键减速程序
	
	Key_Val=Key_Read();//读取按下的键码值
	Key_Down=Key_Val&(Key_Val^Key_Old);//捕捉下降沿
	//Key_Up=~Key_Val&(Key_Val^Key_Old);
	Key_Old=Key_Val;//辅助扫描
	
	switch(Key_Down)
	{
		case 1://启动
			if(Seg_Mode == 0)
				System_Flag =1;
		break;
		case 3://切换
			if(Seg_Mode ==1)
				Time_Count=Set_Dat[Set_Dat_Index];
			Seg_Mode^=1;
		break;
		case 4://设置
			if(Seg_Mode == 1)
			{
				if(++Set_Dat_Index==3)
					Set_Dat_Index=0;
			}
		break;
		case 2:
			if(Seg_Mode == 0)
				{
					Time_Count=Set_Dat[Set_Dat_Index];
				}
		break;
	}
}

//信息处理函数
void Seg_Proc()
{
	if(Seg_Slow_Down)return;
	Seg_Slow_Down=1;//数码管减速程序
	
	Seg_Buf[0]=Seg_Mode+1;
	if(Seg_Mode == 0)//系统处于显示界面
	{
		Seg_Buf[4]=Time_Count/10;
		Seg_Buf[5]=Time_Count%10;
	}
	else//系统处于设置界面
	{
		if(Seg_Flag ==1)
		{
			Seg_Buf[4]=Set_Dat[Set_Dat_Index]/10;
			Seg_Buf[5]=Set_Dat[Set_Dat_Index]%10;
		}
		else
		{
			Seg_Buf[4]=10;
			Seg_Buf[5]=10;
		}
	}
}

//其他显示函数
void Led_Proc()
{
	if(Time_Count ==0)
	{
		P1=0x00;
		P2_3=0;
	}
	else
	{
		P1=0xff;
		P2_3=1;
	}
}

//定时器0初始化函数
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;
}

//定时器0中断服务函数
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]);
	if(System_Flag ==1)
	{
		if(++Timer_1000ms ==1000)
		{
			Timer_1000ms=0;
			Time_Count--;
			if(Time_Count ==255)
				Time_Count=0;
		}
	}
	if(++Timer_500ms ==500)
	{
		Timer_500ms=0;
		Seg_Flag^=1;//取反
	}
}

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