欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
單片機狀態機來掃描鍵盤程序 調時狀態加減會出問題
[打印本頁]
作者:
殿堂之上
時間:
2023-10-25 17:42
標題:
單片機狀態機來掃描鍵盤程序 調時狀態加減會出問題
用狀態機來掃描鍵盤,有時按了會出現錯亂,不知道哪里出問題了
單片機源程序如下:
#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);
}
}
復制代碼
作者:
wulin
時間:
2023-10-25 21:01
void KeyProcess(void)
{
switch(KeyValue)
{
case K2:/* */break;
case K3:/* */break;
case K4:/* */break;
case K5:/* */break;
}
KeyValue=0x00;//鍵值用后要清0
}
void KeyScan(void)
{
P3=0x0f;
if(P3!=0x0f)
KeyValue=P3;
KeyProcess();
}
作者:
殿堂之上
時間:
2023-10-26 15:31
wulin 發表于 2023-10-25 21:01
void KeyProcess(void)
{
switch(KeyValue)
你這樣就不是用狀態機的方式了,我找到原因了,是值設置的不對,還有調時進去時默認改時。
case K3:
if(Flag_Change==1)
{
if(Flag_Time==0)
{
Hour++;
if(Hour==
24
)Hour=0;
}
if(Flag_Time==1)
{
Minute++;
if(Minute==
60
)Minute=0;
}
if(Flag_Time==2)
{
Second++;
if(Second==
60
)Second=0;
}
}
break;
case K4:
if(Flag_Change==1)
{
if(Flag_Time==0)
{
Hour--;
if(Hour==
255
)Hour=23;
}
if(Flag_Time==1)
{
Minute--;
if(Minute==
255
)Minute=59;
}
if(Flag_Time==2)
{
Second--;
if(Second==
255
)Second=59;
}
}
break;
case K5:
if(Flag_Change==0)
{
Flag_Change=1;
Flag_Time=0;
}
else
Flag_Change=0;
break;
、、、、、、、、、、、、、、、、、、、、、、、、、、、
作者:
圣博朗西斯
時間:
2023-10-27 09:27
大體看了一下你的代碼框架,寫8位機思路是對的,但是按鍵的處理是不建議放中段處理的,你中斷定時到了后,在While大循環里去刷新按鍵進行消抖
keytemp=0;
if(pin_adkey==0) // adckeyvolt<=20
{
keytemp=1;
}
直接向上面給出鍵值而后對鍵值進行定時刷新
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1