#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit k1=P3^1; //定义P31口是k1
sbit k2=P3^0; //定义P30口是k2
sbit k3=P3^2; //定义P32口是k3
sbit k4=P3^3; //定义P33口是k4
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u16 smgwei[8]={5,5,10,9,5,10,3,2};
u8 setwei=0; //调整时间各位的位置参数,默认为0,即不调整任何位。
u16 times[8];//循环次数累计,累计指令条数,粗略估算时间,控制被调整位闪烁频率。
u8 code smgduan[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,//数码管段选,显示0~9的值
0x80};//0x40数码管显示是短横
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : keypros
* 函数功能 : 按键处理函数,判断按键K1是否按下
*******************************************************************************/
void keypros()
{
if(k1==0) //检测按键K1是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(k1==0) //再次判断按键是否按下
{
setwei++;
if(setwei>8)
setwei=0;
TR0=0;
}
while(!k1); //检测按键是否松开
}
if(k2==0) //检测按键k2是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(k2==0) //再次判断按键是否按下
{
switch(setwei) //先判断调整时间中的哪一位,然后被选中位的数值自减
{ //减法可能越界,所以需要根据不同各位的进制来控制越界
case(1):smgwei[0]--;if(smgwei[0]==-1&&smgwei[1]==0) {smgwei[0]=9;smgwei[1]=5;}
else if(smgwei[0]==-1) {smgwei[0]=9;smgwei[1]--; }break;
case(2):smgwei[1]--;if(smgwei[1]==-1) {smgwei[1]=5;smgwei[3]--;}break;
case(3):;break;
case(4):smgwei[3]--;if(smgwei[3]==-1&&smgwei[4]==0) {smgwei[3]=9;smgwei[4]=5;}
else if(smgwei[3]==-1) {smgwei[3]=9;smgwei[4]--; }break;
case(5):smgwei[4]--;if(smgwei[4]==-1) {smgwei[4]=5;smgwei[6]--;}break;
case(6):;break;
case(7):smgwei[6]--;if(smgwei[7]==0&&smgwei[6]==-1)
{smgwei[6]=3;smgwei[7]=2;}
else if(smgwei[6]==-1)
{smgwei[6]=9;smgwei[7]--; }
break;
case(8):smgwei[7]--;if(smgwei[7]==-1) smgwei[7]=2;break;
}
}
while(!k2); //检测按键是否松开
}
if(k3==0) //检测按键K1是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(k3==0) //再次判断按键是否按下
{
switch(setwei) //和减法类似,也是先判断被选中的位。再修改其值。
{ //不过加法的越界问题在main秒数递增进位过程中处理了
case(1):smgwei[0]++;break;
case(2):smgwei[1]++;break;
case(3):;break;
case(4):smgwei[3]++;break;
case(5):smgwei[4]++;break;
case(6):;break;
case(7):smgwei[6]++;break;
case(8):smgwei[7]++;break;
}
}
while(!k3); //检测按键是否松开
}
if(k4==0) //检测按键K1是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(k4==0) //再次判断按键是否按下
{
TR0=1;
setwei=9;
}
while(!k4); //检测按键是否松开
}
}
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
void show() //修改后数码管显示函数
{
u8 j;
P2|=0x1c; //8个数码管 ,使用for循环,轮流选通这8个数码管并传送不同的数据给P0
for (j=0;j<8;j++)
{ //同时根据条件,选择数码管常亮或者闪烁
P2+=4;
P0=(setwei==(j+1)&×[j]>500)?0x00:smgduan[smgwei[j]];
times[j]++;
if (times[j]>1000) times[j]=0;
delay(10);P0=0x00;
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Timer0Init(); //定时器0初始化
while(1)
{
keypros(); //按键处理函数
if(smgwei[0]==10) {smgwei[0]=0;smgwei[1]+=1;}
if(smgwei[1]==6) {smgwei[1]=0;smgwei[3]+=1;}
if(smgwei[3]==10) {smgwei[3]=0;smgwei[4]+=1;}
if(smgwei[4]==6) {smgwei[4]=0;smgwei[6]+=1;}
if(smgwei[6]==10) {smgwei[6]=0;smgwei[7]+=1;}
if((smgwei[7]*10+smgwei[6])>=24) {smgwei[6]=0;smgwei[7]=0;}
show();
}
}
void Timer0() interrupt 1
{
static u16 i;
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
i++;
if(i==1000)
{
i=0;
smgwei[0]++;
}
}
|