目录
前言:
功能说明:通过按键1控制模式选择:模式0------时钟显示模式,模式1:------时钟设置模式
通过time[ ]数组存放时分秒三个时间单元,同时由按键2控制时间单元的可调控
制,按键3控制时间单元数值的增加,按键4控制时间单元数值的减少.(需要注意的是
按键与数码管均通过定时器0扫描)
模块化代码:
定时器扫描按键代码:
#include"reg52.h"
#include"Delay.h"
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
unsigned char Dep_key_value;
unsigned char Dep_key_scan(void)
{
unsigned char temp;
temp=Dep_key_value;//将按键键值赋值给中间变量
Dep_key_value=0;//清零
return temp;
}
//函数名:获取独立按键状态函数
//形参变量:无
//返回值return:Dep_key_number:独立按键键值
unsigned char key_GetState(void)
{
unsigned char Dep_key_number=0;
if(KEY1==0)Dep_key_number=1;
if(KEY2==0)Dep_key_number=2;
if(KEY3==0)Dep_key_number=3;
if(KEY4==0)Dep_key_number=4;
return Dep_key_number;
}
void key_loop(void)
{
static unsigned char LastState,NowState;//定义前后两次按键状态,判断时按下触发还是松手后触发
LastState=NowState;
NowState=key_GetState();//获取现状态按键状态
if(LastState==1 && NowState==0)//按键松手后触发
Dep_key_value=1;
if(LastState==2 && NowState==0)//按键松手后触发
Dep_key_value=2;
if(LastState==3 && NowState==0)//按键松手后触发
Dep_key_value=3;
if(LastState==4 && NowState==0)//按键松手后触发
Dep_key_value=4;
}
定时器扫描数码管:
#include"reg52.h"
#define SMG_DUANXUAN_PORT P0
sbit HCC=P2^4;
sbit HCB=P2^3;
sbit HCA=P2^2;//74HC138三输入引脚,同时控制数码管的位选
unsigned char code smg_code[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};//字形码0-9显示(共阴数码管)
unsigned char Smg_Buffer[]={10,10,10,10,10,10,10,10,10};//初始时,数码管不显示
//函数名:数码管显示数值缓存区(主函数调用)
//形参变量:wei:位选 num_value:对应数码管显示的数字
//返回值return:无
void Set_Smg_Buffer(unsigned char wei,num_value)
{
Smg_Buffer[wei]=num_value;//设置数码管缓存区
}
//函数名:定时器扫描数码管函数
//形参变量:wei:位选 num:对应数码管显示的数字
//返回值return:无
void smg_scan(unsigned char wei,num)
{
SMG_DUANXUAN_PORT=0x00;//消影
switch (wei)
{
case 1:HCC=1;HCB=1;HCA=1;break;
case 2:HCC=1;HCB=1;HCA=0;break;
case 3:HCC=1;HCB=0;HCA=1;break;
case 4:HCC=1;HCB=0;HCA=0;break;
case 5:HCC=0;HCB=1;HCA=1;break;
case 6:HCC=0;HCB=1;HCA=0;break;
case 7:HCC=0;HCB=0;HCA=1;break;
case 8:HCC=0;HCB=0;HCA=0;break;
}
SMG_DUANXUAN_PORT=smg_code[num];
}
//函数名:数码管驱动函数(定时器中断调用)
//形参变量:无
//返回值return:无
void smg_loop(void)
{
static unsigned char i=1;
smg_scan(i,Smg_Buffer[i]);
i++;
if(i==9)
i=1;//1-8循环扫描数码管
}
主函数main代码:
/*********************************************
功能说明:通过数码管显示,制作一个可调电子时钟
*********************************************/
#include"reg52.h"
#include"key.h"
#include"time0_init.h"
#include"smg_Tscan.h"
#define u8 unsigned char
#define u16 unsigned int
char time[]={21,0,01};//时 分 秒
u8 key_value;//按键键值
u8 mode,state_select;//设置模式索引
u8 Select_flash_flag;//选择闪烁标志位
void Time_Show(void)//时间显示模式
{
TR1=1;//打开定时器1
if(time[2]==60)//60s进位
time[1]++;
if(time[1]==60)
time[0]++;
time[0]=time[0]%24;//越界判断
time[1]=time[1]%60;
time[2]=time[2]%60;
Set_Smg_Buffer(1,time[0]/10%10);
Set_Smg_Buffer(2,time[0]/1%10);
Set_Smg_Buffer(4,time[1]/10%10);
Set_Smg_Buffer(5,time[1]/1%10);
Set_Smg_Buffer(7,time[2]/10%10);
Set_Smg_Buffer(8,time[2]/1%10);
}
void Time_Set(void)//时间设置模式
{
TR1=0;//关闭定时器1
if(key_value==2)//时间单元选择
state_select=++state_select%3;//时 分 秒单元选择设置
if(key_value==3)//自增键
{
time[state_select]++;
time[0]=time[0]%24;//越界判断
time[1]=time[1]%60;
time[2]=time[2]%60;
}
if(key_value==4)//自减键
{
time[state_select]--;
if(time[0]<0)//越界判断
time[0]=23;
if(time[1]<0)
time[1]=59;
if(time[2]<0)
time[2]=59;
}
if(state_select==0 && Select_flash_flag==1)
{
Set_Smg_Buffer(1,time[0]/10%10);
Set_Smg_Buffer(2,time[0]/1%10);
}
else
{
Set_Smg_Buffer(1,10);
Set_Smg_Buffer(2,10);
}
if(state_select==1 && Select_flash_flag==1)
{
Set_Smg_Buffer(4,time[1]/10%10);
Set_Smg_Buffer(5,time[1]/1%10);
}
else
{
Set_Smg_Buffer(4,10);
Set_Smg_Buffer(5,10);
}
if(state_select==2 && Select_flash_flag==1)
{
Set_Smg_Buffer(7,time[2]/10%10);
Set_Smg_Buffer(8,time[2]/1%10);
}
else
{
Set_Smg_Buffer(7,10);
Set_Smg_Buffer(8,10);
}
switch(state_select)
{
case 0:{
Set_Smg_Buffer(4,time[1]/10%10);
Set_Smg_Buffer(5,time[1]/1%10);
Set_Smg_Buffer(7,time[2]/10%10);
Set_Smg_Buffer(8,time[2]/1%10);
}break;
case 1:{
Set_Smg_Buffer(1,time[0]/10%10);
Set_Smg_Buffer(2,time[0]/1%10);
Set_Smg_Buffer(7,time[2]/10%10);
Set_Smg_Buffer(8,time[2]/1%10);
}break;
case 2:{
Set_Smg_Buffer(1,time[0]/10%10);
Set_Smg_Buffer(2,time[0]/1%10);
Set_Smg_Buffer(4,time[1]/10%10);
Set_Smg_Buffer(5,time[1]/1%10);
}break;
}
}
void main()
{
time0_init();//定时器0初始化
time1_init();//定时器1初始化
Set_Smg_Buffer(3,11);
Set_Smg_Buffer(6,11);//初始显示-字符
while(1)
{
key_value=Dep_key_scan();//传递键值
if(key_value==1)//控制模式选择-----0:时间显示模式 1:时间设置模式
{
mode=++mode%2;
}
switch(mode)
{
case 0:Time_Show();state_select=0;break;//进入时间显示模式
case 1:Time_Set();break;//进入时间设置模式
}
}
}
void time0_int(void) interrupt 1 //中断服务函数
{
static u16 counter0=0;
TH0=0XFC;
TL0=0X66;//定时器赋初值,每次定时1ms
counter0++;
key_loop();//按键驱动函数扫描
smg_loop();//数码管驱动函数扫描
if(counter0==500)
{
counter0=0;
Select_flash_flag=!Select_flash_flag;//每0.5s闪烁一次
}
}
void time1_int(void) interrupt 3 //中断服务函数
{
static u16 counter1=0;
TH1=0XFC;
TL1=0X66;//定时器赋初值,每次定时1ms
counter1++;
if(counter1==1000)
{
counter1=0;
time[2]++;//秒自增
}
}