用状态机来扫描键盘,有时按了会出现错乱,不知道哪里出问题了
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define SXLed_P P0
- #define K5 0x07
- #define K4 0x0b
- #define K3 0x0d
- #define K2 0x0e
- unsigned int i;
- unsigned char KeyValue,KeyValueTemp,StateNo,Flag_Time;
- bit Flag_05s,Flag_1s,Flag_Change,Flag_Hide; //位标志
- unsigned char SX[8]; //数码管数据缓存,位标志
- unsigned char Hour,Minute,Second; //时分秒
- sbit SXLed_W=P2^7; //数码管位选
- sbit SXLed_D=P2^6; //数码管段选
- sbit bp=P2^3;
- unsigned char code Number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7F,
- 0x6F,0x40,0x80,0x00}; //共阴极数码管0-9-.灭
- void Delay(unsigned char ); //毫秒延时函数
- void Init(void); //数据初始化函数
- void T0_Init(void); //T0中断初始化函数
- void SXLed (unsigned char location,unsigned char Num);//数码管显示函数
- void Start_Screen(void); //开机显示画面函数
- void Time(void); //时分秒进位函数
- void Hex_BCD(void); //数据转换并送到数码管数缓存函数
- void KeyScan(void); //按键扫描函数(状态机法)
- void KeyProcess(void); //按键处理函数
- void main(void)
- {
- Delay(100); //开机延时
- Init(); //变量初始化
- T0_Init(); //定时器T0初始化
- Start_Screen(); //开机画面
- // P1=0x00;
- while(1)
- {
- if(Flag_05s==1) //0.5秒到了
- {
- Flag_05s=0;//0.5秒到状态清0
- Hex_BCD();//数据转换并送到数码管数缓存
- if(Flag_Change!=0)//调时状态
- {
- Flag_Hide=!Flag_Hide;//隐藏标志
- if ((Flag_Hide==1)&&(Flag_Time==0))//调时状态时闪烁
- {
- SX[7]=12;
- SX[6]=12;
- }
- if ((Flag_Hide==1)&&(Flag_Time==1))//调时状态分闪烁
- {
- SX[4]=12;
- SX[3]=12;
- }
- if ((Flag_Hide==1)&&(Flag_Time==2))//调时状态秒闪烁
- {
- SX[1]=12;
- SX[0]=12;
- }
- }
- }
- }
- }
- void Init(void)
- {
- i=0;
- Hour=23;
- Minute=59;
- Second=50;
- Flag_05s=0;
- Flag_1s=0;
- Flag_Change=0;
- Flag_Hide=0;
- StateNo=1;
- KeyValue=0;
- KeyValueTemp=0;
- Flag_Time=0;
- }
- void T0_Timer(void) interrupt 1
- {
- TH0=0xf8; //定时2毫秒高四位初值重装
- TL0=0xcd; //定时2毫秒高四位初值重装
- SXLed(i%8,SX[i%8]); //数码管扫描显示
- i++;
- if(!(i%5)) KeyScan(); //按键扫描
- if(!(i%250)) //0.5秒到了
- {
- // P1=~P1; //指示灯0.5秒交替闪烁
- Flag_05s=1; //0.5秒标志置1
- Flag_1s=!Flag_1s; //1秒标志置取反
- if(Flag_1s==0) //1秒到了
- if(Flag_Change==1) //是否调时状态
- _nop_(); //是,啥也不干
- else
- Time(); //否,时间变动
- }
- }
- void KeyProcess(void)
- {
- switch (KeyValue)
- {
- case K2:
- if(Flag_Change==1)
- {
- Flag_Time++;
- if(Flag_Time==3)Flag_Time=0;
- }
- break;
- case K3:
- if(Flag_Change==1)
- {
- if(Flag_Time==0)
- {
- Hour++;
- if(Hour==23)Hour=0;
- }
- if(Flag_Time==1)
- {
- Minute++;
- if(Minute==59)Minute=0;
- }
- if(Flag_Time==2)
- {
- Second++;
- if(Second==59)Second=0;
- }
- }
- break;
- case K4:
- if(Flag_Change==1)
- {
- if(Flag_Time==0)
- {
- Hour--;
- if(Hour==0)Hour=23;
- }
- if(Flag_Time==1)
- {
- Minute--;
- if(Minute==0)Minute=59;
- }
- if(Flag_Time==2)
- {
- Second--;
- if(Second==0)Second=59;
- }
- }
- break;
- case K5:
- if(Flag_Change==0)
- Flag_Change=1;
- else
- Flag_Change=0;
- break;
- default:
- Flag_Change=0;
- break;
- }
- }
- void KeyScan(void)
- {
- P3=P3|0x0f;
- if (StateNo==1)
- {
- if ((P3&0x0f)!=0x0f)
- StateNo=2;
- else
- StateNo=1;
- }
- else if (StateNo==2)
- {
- if ((P3&0x0f)!=0x0f)
- {
- KeyValueTemp=P3&0x0f;
- StateNo=3;
- }
- else
- StateNo=1;
- }
- else if (StateNo==3)
- {
- if ((P3&0x0f)==0x0f)
- {
- KeyValue=KeyValueTemp;
- StateNo=4;
- }
- else
- {
- ;
- }
- }
- else if (StateNo==4)
- {
- KeyProcess();
- StateNo=1;
- }
- else
- StateNo=1;
- }
- void Hex_BCD(void)
- {
- SX[0]=Second%10;
- SX[1]=Second/10;
- SX[2]=10;
- SX[3]=Minute%10;
- SX[4]=Minute/10;
- SX[5]=10;
- SX[6]=Hour%10;
- SX[7]=Hour/10;
- }
- void Time(void)
- {
- Second++;
- if (Second==60)
- {
- Second=0;
- Minute++;
- if(Minute==60)
- {
- Minute=0;
- Hour++;
- if(Hour==24)Hour=0;
- }
- }
- }
- void T0_Init(void)
- {
- TMOD|=0x01; //定时器T0工作在16位定时模式
- EA=1; //开总中断
- ET0=1; //开定时器中断
- TR0=1; //启动定时器
- TH0=0xf8; //定时2毫秒高四位初值重装
- TL0=0xcd; //定时2毫秒高四位初值重装
- }
- void SXLed (unsigned char location,unsigned char Num)//location显示位置,num显示数字
- {
- SXLed_P=0xff; //消影
- SXLed_W=1; //打开位选锁存器
- SXLed_P=~(0x80>>location); //送位码
- SXLed_W=0; //锁存位选数据
- SXLed_D=1; //打开段选锁存器
- SXLed_P=Number[Num]; //送段码
- SXLed_D=0; //锁存段选数据
- }
- void Start_Screen(void) //开机显示画面
- {
- unsigned char k,j;
- for (k=0;k<11;k++)
- {
- for (j=0;j<8;j++)
- if(k==0)
- SX[j]=10;
- else
- SX[j]=k-1;
- Delay(1000);
- }
- }
- void Delay(unsigned char ms) //@11.0592MHz延时
- {
- unsigned char data i, j;
- while(ms--)
- {
- _nop_();
- i = 2;
- j = 198;
- do
- {
- while (--j);
- } while (--i);
- }
- }
复制代码
|