標(biāo)題: 單片機(jī)狀態(tài)機(jī)按鍵程序 支持短按和長(zhǎng)按,可移植性好 [打印本頁(yè)]

作者: 2006sunmoon    時(shí)間: 2022-9-29 11:55
標(biāo)題: 單片機(jī)狀態(tài)機(jī)按鍵程序 支持短按和長(zhǎng)按,可移植性好
狀態(tài)機(jī)按鍵程序,可移植性好,支持短按和長(zhǎng)按。親測(cè)可用。
單片機(jī)源程序如下:
  1. #include <iom16.h>
  2. #include <intrinsics.h>
  3. #include <stdbool.h>//位變量頭文件
  4. #include <iomacro.h>
  5. #include "keyboard.h"

  6. #define key_state_init 0   //按鍵的初始狀態(tài)
  7. #define key_state_ok 1   //按鍵被按下的狀態(tài)
  8. #define key_state_long 2   //按鍵被長(zhǎng)按狀態(tài)
  9. //#define key_state_continue 3   //按鍵被連續(xù)按下?tīng)顟B(tài)
  10. #define key_state_release 4   //按鍵釋放的狀態(tài)

  11. unsigned char KeyRead()
  12. {
  13.   static unsigned int key_timenum=0;//按鍵長(zhǎng)按時(shí)間變量
  14.   static unsigned char key_state=0; //按鍵的狀態(tài)
  15.   static unsigned char key_num=0;//保存按鍵按鍵釋放時(shí)的值
  16.   static bool key_LONG=0;//記錄長(zhǎng)按釋放
  17.   unsigned char  key_return=0;        //按鍵返回值       
  18.   unsigned char key_press; //保存按鍵按下的端口值       

  19.   key_press =(port^0xFF)&0XFF; // 讀按鍵I/O電平

  20.   switch (key_state)
  21.   {
  22.     case key_state_init://按鍵的初始狀態(tài)
  23.         if(key_press)//如果按鍵被按下
  24.         {
  25.           key_state=key_state_ok;//則把key_state按鍵狀態(tài)置為按鍵確認(rèn)狀態(tài)
  26.         }
  27.          break;
  28.     case key_state_ok://按鍵確認(rèn)狀態(tài)
  29.         if(key_press)//如果按鍵被按下
  30.         {
  31.           key_num=key_press;// 按鍵I/O電平保存
  32.           key_state=key_state_long;//則把key_state按鍵狀態(tài)置為按鍵被長(zhǎng)按狀態(tài)
  33.         }
  34.         else
  35.           key_state=key_state_init;        //如果按鍵是抖動(dòng)則返回按鍵的初始狀態(tài)
  36.         
  37.          break;
  38.     case key_state_long://按鍵被長(zhǎng)按狀態(tài)
  39.         if(key_press)//如果按鍵被按下
  40.         {
  41.           if(!key_LONG)//如果上次有長(zhǎng)按事件發(fā)生,長(zhǎng)按時(shí)間就不再計(jì)時(shí)。
  42.           {
  43.               if (++key_timenum>=KEY_LONG_PERIOD)//達(dá)到長(zhǎng)按設(shè)置值時(shí)
  44.               {
  45.                 key_timenum=0;
  46.                 key_return=(key_press+KEY_LONGSIGN);//返回按鍵值加個(gè)數(shù)來(lái)區(qū)別單按和長(zhǎng)按
  47.                 key_LONG=1;//標(biāo)記長(zhǎng)按事件發(fā)生
  48.               }
  49.           }
  50.           else
  51.             key_return=(key_press+KEY_LONGSIGN);//返回按鍵值加個(gè)數(shù)來(lái)區(qū)別單按和長(zhǎng)按
  52.         }
  53.         else
  54.           key_state=key_state_release;        //則把key_state按鍵狀態(tài)置為按鍵被釋放狀態(tài)       
  55.          break;               
  56.     case key_state_release://按鍵釋放狀態(tài)

  57.         if (key_LONG)//如果有長(zhǎng)按事件發(fā)生
  58.         {
  59.           if(!key_press)//如果按鍵全部釋放
  60.           {
  61.             key_return=0;//返回值清0
  62.             key_state=key_state_init;//則把key_state按鍵狀態(tài)置為按鍵初始狀態(tài)
  63.             key_timenum=0;//計(jì)數(shù)清0
  64.             key_LONG=0;//長(zhǎng)按標(biāo)記清0
  65.           }
  66.           else//如果按鍵沒(méi)有釋放
  67.           {
  68.              key_state=key_state_release;//則繼續(xù)把key_state按鍵狀態(tài)置為按鍵被釋放狀態(tài)       
  69.           }  
  70.         }
  71.         else//如果沒(méi)有長(zhǎng)按事件發(fā)生
  72.         {
  73.           if(!key_press)//如果按鍵全部釋放
  74.           {
  75.             key_return=key_num;
  76.             key_state=key_state_init;//則把key_state按鍵狀態(tài)置為按鍵初始狀態(tài)
  77.             key_timenum=0;//計(jì)數(shù)清0
  78.           }
  79.           else
  80.           {
  81.             key_state=key_state_release;//則繼續(xù)把key_state按鍵狀態(tài)置為按鍵被釋放狀態(tài)       
  82.           }  
  83.         }                       
  84.          break;
  85.     }
  86.     return key_return;                 
  87. }
復(fù)制代碼
  1. #ifndef __KEYBOARD_H__
  2. #define __KEYBOARD_H__

  3. #define K1 0X01//設(shè)定按鍵位置
  4. #define K2 0X02//設(shè)定按鍵位置
  5. #define K3 0X04//設(shè)定按鍵位置
  6. #define K4 0X08//設(shè)定按鍵位置
  7. #define K5 0X10//設(shè)定按鍵位置
  8. #define K6 0X20//設(shè)定按鍵位置
  9. #define K7 0X40//設(shè)定按鍵位置
  10. #define K8 0X80//設(shè)定按鍵位置
  11. #define L_K1 0X01+KEY_LONGSIGN//設(shè)定按鍵位置
  12. #define L_K2 0X02+KEY_LONGSIGN//設(shè)定按鍵位置
  13. #define L_K3 0X04+KEY_LONGSIGN//設(shè)定按鍵位置
  14. #define L_K4 0X08+KEY_LONGSIGN//設(shè)定按鍵位置
  15. #define L_K5 0X10+KEY_LONGSIGN//設(shè)定按鍵位置
  16. #define L_K6 0X20+KEY_LONGSIGN//設(shè)定按鍵位置
  17. #define L_K7 0X40+KEY_LONGSIGN//設(shè)定按鍵位置
  18. #define L_K8 0X80+KEY_LONGSIGN//設(shè)定按鍵位置
  19. #define port PINA//設(shè)定按鍵端口
  20. #define KEY_LONGSIGN 5//設(shè)定長(zhǎng)按按鍵與普通按鍵差值
  21. #define KEY_LONG_PERIOD 150//定義長(zhǎng)按鍵時(shí)間,消抖時(shí)間*時(shí)間數(shù)
  22. unsigned char KeyRead();
  23. #endif
復(fù)制代碼





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1