久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1139|回復: 3
收起左側

單片機狀態機來掃描鍵盤程序 調時狀態加減會出問題

[復制鏈接]
ID:1095802 發表于 2023-10-25 17:42 | 顯示全部樓層 |閱讀模式
用狀態機來掃描鍵盤,有時按了會出現錯亂,不知道哪里出問題了
單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define SXLed_P P0
  4. #define K5 0x07
  5. #define K4 0x0b
  6. #define K3 0x0d
  7. #define K2 0x0e
  8. unsigned int i;
  9. unsigned char KeyValue,KeyValueTemp,StateNo,Flag_Time;
  10. bit Flag_05s,Flag_1s,Flag_Change,Flag_Hide;                                                        //位標志
  11. unsigned char SX[8];                        //數碼管數據緩存,位標志
  12. unsigned char Hour,Minute,Second;        //時分秒
  13. sbit SXLed_W=P2^7;                                //數碼管位選
  14. sbit SXLed_D=P2^6;                                //數碼管段選
  15. sbit bp=P2^3;
  16. unsigned  char code Number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7F,
  17. 0x6F,0x40,0x80,0x00};                                //共陰極數碼管0-9-.滅
  18. void Delay(unsigned char ); //毫秒延時函數
  19. void Init(void);                                                //數據初始化函數
  20. void T0_Init(void);                                        //T0中斷初始化函數
  21. void SXLed (unsigned char location,unsigned char Num);//數碼管顯示函數
  22. void Start_Screen(void);                //開機顯示畫面函數
  23. void Time(void);                                                //時分秒進位函數
  24. void Hex_BCD(void);                                        //數據轉換并送到數碼管數緩存函數
  25. void KeyScan(void);                                        //按鍵掃描函數(狀態機法)
  26. void KeyProcess(void);                        //按鍵處理函數
  27. void main(void)
  28. {
  29.         Delay(100);                                                                //開機延時
  30.         Init();                                                                                //變量初始化                                
  31.         T0_Init();                                                                //定時器T0初始化
  32.   Start_Screen();                                                //開機畫面
  33. //        P1=0x00;
  34.         while(1)
  35.         {        
  36.                 if(Flag_05s==1)        //0.5秒到了
  37.                 {        
  38.                         Flag_05s=0;//0.5秒到狀態清0
  39.                         Hex_BCD();//數據轉換并送到數碼管數緩存
  40.                         if(Flag_Change!=0)//調時狀態
  41.                         {
  42.                                 Flag_Hide=!Flag_Hide;//隱藏標志
  43.                                 if ((Flag_Hide==1)&&(Flag_Time==0))//調時狀態時閃爍
  44.                                 {
  45.                                         SX[7]=12;
  46.                                         SX[6]=12;
  47.                                 }
  48.                                 if ((Flag_Hide==1)&&(Flag_Time==1))//調時狀態分閃爍
  49.                                 {
  50.                                         SX[4]=12;
  51.                                         SX[3]=12;
  52.                                 }
  53.                                 if ((Flag_Hide==1)&&(Flag_Time==2))//調時狀態秒閃爍
  54.                                 {
  55.                                         SX[1]=12;
  56.                                         SX[0]=12;
  57.                                 }
  58.                         }
  59.                 }        
  60.         }                        
  61. }
  62. void Init(void)
  63. {
  64.         i=0;
  65.         Hour=23;
  66.         Minute=59;
  67.         Second=50;
  68.         Flag_05s=0;
  69.         Flag_1s=0;
  70.         Flag_Change=0;
  71.         Flag_Hide=0;
  72.         StateNo=1;
  73.         KeyValue=0;
  74.         KeyValueTemp=0;
  75.         Flag_Time=0;
  76. }
  77. void T0_Timer(void) interrupt 1
  78. {
  79.         TH0=0xf8;                                                                        //定時2毫秒高四位初值重裝
  80.         TL0=0xcd;                                                                        //定時2毫秒高四位初值重裝
  81.         SXLed(i%8,SX[i%8]);                                //數碼管掃描顯示
  82.         i++;
  83.         if(!(i%5))        KeyScan();                //按鍵掃描
  84.         if(!(i%250))                                                        //0.5秒到了
  85.         {        
  86. //                P1=~P1;                                                                //指示燈0.5秒交替閃爍
  87.                 Flag_05s=1;                                                        //0.5秒標志置1
  88.                 Flag_1s=!Flag_1s;                                //1秒標志置取反
  89.                 if(Flag_1s==0)                                        //1秒到了
  90.                         if(Flag_Change==1)                //是否調時狀態
  91.                                 _nop_();                                                //是,啥也不干
  92.                         else
  93.                         Time();                                                                //否,時間變動
  94.         }
  95. }

  96. void         KeyProcess(void)
  97. {
  98.         switch (KeyValue)
  99.         {
  100.                 case K2:
  101.                                                 if(Flag_Change==1)
  102.                                                 {
  103.                                                         Flag_Time++;
  104.                                                         if(Flag_Time==3)Flag_Time=0;
  105.                                                 }
  106.                                                 break;
  107.                 case K3:
  108.                                                 if(Flag_Change==1)
  109.                                                 {
  110.                                                         if(Flag_Time==0)        
  111.                                                         {
  112.                                                                 Hour++;
  113.                                                                 if(Hour==23)Hour=0;
  114.                                                         }
  115.                                                         if(Flag_Time==1)        
  116.                                                         {
  117.                                                                 Minute++;
  118.                                                                 if(Minute==59)Minute=0;
  119.                                                         }
  120.                                                         if(Flag_Time==2)        
  121.                                                         {
  122.                                                                 Second++;
  123.                                                                 if(Second==59)Second=0;
  124.                                                         }
  125.                                                 }        
  126.                                                 break;                                       
  127.                 case K4:
  128.                                                 if(Flag_Change==1)
  129.                                                 {
  130.                                                         if(Flag_Time==0)        
  131.                                                         {
  132.                                                                 Hour--;
  133.                                                                 if(Hour==0)Hour=23;
  134.                                                         }
  135.                                                         if(Flag_Time==1)        
  136.                                                         {
  137.                                                                 Minute--;
  138.                                                                 if(Minute==0)Minute=59;
  139.                                                         }
  140.                                                         if(Flag_Time==2)        
  141.                                                         {
  142.                                                                 Second--;
  143.                                                                 if(Second==0)Second=59;
  144.                                                         }
  145.                                                 }
  146.                                                 break;
  147.                 case K5:        
  148.                                                 if(Flag_Change==0)
  149.                                                         Flag_Change=1;
  150.                                                 else
  151.                                                         Flag_Change=0;
  152.                                                 break;
  153.                 default:
  154.                                                 Flag_Change=0;        
  155.                                                 break;        
  156.         }
  157. }
  158. void KeyScan(void)
  159. {
  160.         P3=P3|0x0f;
  161.         if (StateNo==1)
  162.         {
  163.                 if ((P3&0x0f)!=0x0f)
  164.                         StateNo=2;
  165.                 else
  166.                         StateNo=1;
  167.         }
  168.         else if (StateNo==2)
  169.         {
  170.                 if ((P3&0x0f)!=0x0f)
  171.                 {
  172.                         KeyValueTemp=P3&0x0f;
  173.                         StateNo=3;
  174.                 }
  175.                 else
  176.                         StateNo=1;               
  177.         }        
  178.         else if (StateNo==3)
  179.         {
  180.                 if ((P3&0x0f)==0x0f)
  181.                 {
  182.                         KeyValue=KeyValueTemp;
  183.                         StateNo=4;
  184.                 }
  185.                 else
  186.                 {
  187.                         ;
  188.                 }        
  189.         }
  190.         else if (StateNo==4)
  191.         {
  192.                 KeyProcess();
  193.                 StateNo=1;
  194.         }
  195.         else
  196.                 StateNo=1;               
  197. }
  198. void Hex_BCD(void)
  199. {
  200.         SX[0]=Second%10;
  201.         SX[1]=Second/10;
  202.         SX[2]=10;
  203.         SX[3]=Minute%10;
  204.         SX[4]=Minute/10;
  205.         SX[5]=10;
  206.         SX[6]=Hour%10;
  207.         SX[7]=Hour/10;
  208. }
  209. void Time(void)
  210. {
  211.         Second++;
  212.         if (Second==60)
  213.         {
  214.                 Second=0;
  215.                 Minute++;
  216.                 if(Minute==60)
  217.                 {
  218.                         Minute=0;
  219.                         Hour++;
  220.                         if(Hour==24)Hour=0;
  221.                 }
  222.         }
  223. }
  224. void T0_Init(void)
  225. {
  226.         TMOD|=0x01;                                                                //定時器T0工作在16位定時模式
  227.         EA=1;                                                                                        //開總中斷
  228.         ET0=1;                                                                                //開定時器中斷
  229.         TR0=1;                                                                                //啟動定時器
  230.         TH0=0xf8;                                                                        //定時2毫秒高四位初值重裝
  231.         TL0=0xcd;                                                                        //定時2毫秒高四位初值重裝
  232. }
  233. void SXLed (unsigned char location,unsigned char Num)//location顯示位置,num顯示數字
  234. {
  235.         SXLed_P=0xff;                                                                        //消影
  236.         SXLed_W=1;                                                                                //打開位選鎖存器
  237.         SXLed_P=~(0x80>>location);                //送位碼
  238.         SXLed_W=0;                                                                                //鎖存位選數據
  239.         SXLed_D=1;                                                                                //打開段選鎖存器
  240.         SXLed_P=Number[Num];                                        //送段碼
  241.         SXLed_D=0;                                                                                //鎖存段選數據
  242. }
  243. void Start_Screen(void)                                        //開機顯示畫面
  244. {
  245.         unsigned char k,j;
  246.         for (k=0;k<11;k++)
  247.         {
  248.                 for (j=0;j<8;j++)
  249.                         if(k==0)
  250.                                 SX[j]=10;
  251.                         else
  252.                                 SX[j]=k-1;
  253.                 Delay(1000);
  254.         }
  255. }
  256. void Delay(unsigned char ms)                        //@11.0592MHz延時
  257. {
  258.         unsigned char data i, j;
  259.         while(ms--)
  260.         {
  261.                 _nop_();
  262.                 i = 2;
  263.                 j = 198;
  264.                 do
  265.                 {
  266.                         while (--j);
  267.                 } while (--i);
  268.         }
  269. }
復制代碼

回復

使用道具 舉報

ID:213173 發表于 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();
}
回復

使用道具 舉報

ID:1095802 發表于 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;
、、、、、、、、、、、、、、、、、、、、、、、、、、、

回復

使用道具 舉報

ID:1097455 發表于 2023-10-27 09:27 | 顯示全部樓層
大體看了一下你的代碼框架,寫8位機思路是對的,但是按鍵的處理是不建議放中段處理的,你中斷定時到了后,在While大循環里去刷新按鍵進行消抖        
keytemp=0;
  if(pin_adkey==0)     //               adckeyvolt<=20      
        {
                  keytemp=1;
        }

直接向上面給出鍵值而后對鍵值進行定時刷新
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕av网 | 国产一区二区精品 | 欧美黄色网 | 亚洲综合久久久 | 91国内精精品久久久久久婷婷 | av高清毛片| 日韩欧美亚洲一区 | 久热中文字幕 | 亚洲精品乱码久久久久久黑人 | 91影片| 先锋av资源在线 | 国产精品区一区二区三 | 伊人久久伊人 | 午夜一区二区三区在线观看 | 日韩免费av一区二区 | 国产精品久久久久一区二区三区 | 免费视频99 | 欧美黄视频 | 伊人操| 少妇av片| 国产黄色麻豆视频 | 国产成人精品在线 | 国内精品成人 | 99精品免费久久久久久久久日本 | 日韩欧美一区二区三区免费观看 | 亚洲精品成人在线 | 91久久爽久久爽爽久久片 | 日韩一区二区三区视频在线观看 | 欧美激情精品久久久久久变态 | 天天久久 | 久久手机视频 | 亚洲黄色片免费观看 | 久久综合国产精品 | 日韩成人性视频 | 午夜激情影院 | 男女视频在线看 | 久久精品国产一区二区三区 | 成人深夜福利 | 日韩电影免费在线观看中文字幕 | 亚洲成人综合网站 | 欧美偷偷 |