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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4416|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

一種全新的單片機按鍵程序?qū)懛ㄋ悸罚埓蠹抑附蹋c評

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:207882 發(fā)表于 2019-7-21 01:11 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
        最近帖子已經(jīng)有人在此提到充分利用CPU中斷的重要性,,再次我就不要說了。此按鍵demo支持短按,長按,多個按鍵同時按下,由于是用掃描的方式,各個按鍵的按下和松獨立處理,不互相干擾,避免要按鍵死等的情況。對于特殊的按鍵消抖時間可單獨一條線掃描檢測。。由于是各個按鍵,一位位檢測,檢測到一位就進(jìn)行處理,之后再進(jìn)行處理下一位,所以有先后順序。廢話不多說,下面講思路,有錯誤的地方大家可以一起學(xué)習(xí),探討,,,,,,,,
      按鍵的最終狀態(tài)無非就兩種,按下或者松開。我用的是STC8單片機,現(xiàn)在的一些增強型或許新型號應(yīng)該內(nèi)部都有上拉電阻,,所以我們是按鍵低電平觸發(fā)。
對于只作為輸入口用于按鍵檢測,,我們可以默認(rèn)他的IO口狀態(tài),不要去操作IO寄存器,,,(如果是即作為輸入又作為輸出的話,,在讀取狀態(tài)的時候記得先寫1,延時2個NOP,再去讀,保證讀取的準(zhǔn)確性),,假設(shè)按鍵沒按下去默認(rèn)就是1了,按鍵按下去就是0,也就是1->0的過程,,松開的話就是0->1,恢復(fù)到最初狀態(tài)。這里就有兩個變化1->0,和0->1,,理解這個之后我們就定義兩個變量 value 變化值 buf 最終狀態(tài)值  我們兩個變化1->0,和0->1進(jìn)行異或就是1,,說明了按鍵有按下或松開的動作,我們就去執(zhí)行對應(yīng)的函數(shù),,執(zhí)行完后按鍵的最終只buf也跟著更新,也就是0(按下) 1(松開),,(一直按下的過程)此時端口值0 和buf0  異或就是0 ,咱就不再去執(zhí)行按鍵按下的程序,,(松開后的過程)此時端口值1 和buf1 異或就是0 ,咱就不再去執(zhí)行按鍵松開的程序,,這樣就保證了按下 或者松開 只執(zhí)行一次動作,,因此加入一些標(biāo)志位。,結(jié)合中斷就可以做一些長按功能了。提供的demo里有做了一個實例是長按2秒開關(guān)蜂鳴器,,其他的按鍵按下或者松開的子函數(shù)用戶自己增加自己需要的功能,,里面只是寫了一些簡單的點燈功能用于調(diào)試,,自己驗證了一下程序是可行,,所以提供出來,,大部分都有注釋,看看有什么不足之處,在進(jìn)行修改,,后面會在此基礎(chǔ)加入矩陣掃描,原理一樣,接著進(jìn)一步完善demo,做成一個能實現(xiàn)操作常見的外設(shè)demo出來,,程序不足之處多多見諒,大家多多批評,一起學(xué)習(xí),,,,,下面按鍵的流程圖,也不知道這個畫得不到,老感覺自己的表達(dá)能力有待提高,,或者也會多發(fā)貼,把自己的一些表達(dá)能力加強,,


1 file文件夾為項目的硬件端口表 功能書 原理圖等資料

2 inc文件 為系統(tǒng)配置文件

3 lib文件 各個外設(shè)文件

4 program文件 為項目文件

單片機源程序如下:
  1. #include<stc8.h>
  2. #include <intrins.h>
  3. sbit         led1=P0^4;
  4. sbit         led2=P0^5;
  5. sbit         led3=P0^6;
  6. sbit         led4=P0^7;
  7. sbit         led5=P1^3;
  8. sbit         led6=P1^4;
  9. sbit         led7=P1^5;
  10. sbit         led8=P1^6;

  11. sbit         beep=P1^7;

  12. #define        D_ScanLine                2                        //定義掃描線的數(shù)量,
  13. #define        D_ESTTime                10                        //單位ms,消除抖動時間。實際以為你外設(shè)消抖時間為準(zhǔn)

  14. #define        P0_key                0xFc                        //定義用到的端口按鍵(低電平有效,用到p00 p01)
  15. //#define        P1_key                0x00                        //定義用到的端口按鍵(低電平有效,用到8個)
  16. #define        P2_key                0x00                        //定義用到的端口按鍵(低電平有效,用到8個)
  17. //#define        P3_key                0x00                        //定義用到的端口按鍵(低電平有效,用到8個)

  18. u8                R_key_buf[D_ScanLine];                //定義存儲每一行按鍵變化后最終的數(shù)值
  19. u8            R_key_value[D_ScanLine];    //定義存儲每一行按鍵變化中的數(shù)值



  20. u8                R_key_douce;                                   //按鍵消抖時基
  21. u8                R_key_num;                                        //按鍵編號(對應(yīng)各個按鍵函數(shù))
  22. u8                D_ScanLineDec;                                //當(dāng)前掃描線

  23. u8                beep_flag;                                        //蜂鳴器標(biāo)志
  24. u16                beep_time;                                        //計時
  25. //按鍵消抖
  26. void        F_key_douce()                  
  27. {
  28.                 if(R_key_douce!=0)
  29.                 {
  30.                          R_key_douce=R_key_douce-1;
  31.                 }
  32. }
  33. //蜂鳴器計時

  34. void        F_beep_time()
  35. {
  36.         if(beep_flag==1)
  37.         {
  38.                  if(beep_time!=0)
  39.                  beep_time=beep_time-1;
  40.         }
  41. }
  42. //蜂鳴器檢測

  43. void        F_beep_check()
  44. {
  45.         if(beep_flag==1)
  46.         {
  47.                  if(beep_time==0)
  48.                    {
  49.                               beep=~beep ;
  50.                            beep_flag=0;
  51.                    }
  52.         }
  53. }


  54. //對應(yīng)按鍵按下子函數(shù)
  55. void        F_key1_dn()
  56. {
  57.          
  58.           led1=~led1;
  59. }
  60. void        F_key2_dn()
  61. {
  62.           led2=~led2;
  63. }                          
  64. void        F_key3_dn()
  65. {
  66.           led3=~led3;
  67. }
  68. void        F_key4_dn()
  69. {
  70.           led4=~led4;
  71. }
  72. void        F_key5_dn()
  73. {

  74. }
  75. void        F_key6_dn()
  76. {

  77. }
  78. void        F_key7_dn()
  79. {

  80. }
  81. void        F_key8_dn()
  82. {

  83. }
  84. void        F_key9_dn()
  85. {
  86.        
  87.           led5=~led5;
  88. }
  89. void        F_key10_dn()
  90. {
  91.           led6=~led6;
  92. }
  93. void        F_key11_dn()
  94. {
  95.          led7=~led7;
  96. }
  97. void        F_key12_dn()
  98. {
  99.          led8=~led8;
  100. }
  101. void        F_key13_dn()
  102. {
  103.                 beep_flag=1;
  104.                 beep_time=0x07d0;        //2秒
  105. }
  106. void        F_key14_dn()
  107. {

  108. }
  109. void        F_key15_dn()
  110. {

  111. }
  112. void        F_key16_dn()
  113. {

  114. }


  115. //------------------------------------------------------
  116. //對應(yīng)按鍵松開子函數(shù)
  117. void        F_key1_up()
  118. {

  119. }
  120. void        F_key2_up()
  121. {
  122. //          R_key_num=8;
  123. //          led=~led;
  124. }
  125. void        F_key3_up()
  126. {
  127. //          R_key_num=8;
  128. //          led=~led;
  129. }
  130. void        F_key4_up()
  131. {
  132. //          R_key_num=8;
  133. //          led=~led;
  134. }
  135. void        F_key5_up()
  136. {
  137. //          R_key_num=8;
  138. //          led=~led;
  139. }
  140. void        F_key6_up()
  141. {
  142. //          R_key_num=8;
  143. //          led=~led;
  144. }
  145. void        F_key7_up()
  146. {
  147. //          R_key_num=8;
  148. //          led=~led;
  149. }
  150. void        F_key8_up()
  151. {
  152. //          R_key_num=8;
  153. //          led1=~led1;
  154. }
  155. void        F_key9_up()
  156. {
  157. //          R_key_num=8;
  158. //          led1=~led1;
  159. }
  160. void        F_key10_up()
  161. {
  162. //          R_key_num=8;
  163. //          led=~led;
  164. }
  165. void        F_key11_up()
  166. {
  167. //          R_key_num=8;
  168. //          led=~led;
  169. }
  170. void        F_key12_up()
  171. {
  172. //          R_key_num=8;
  173. //          led=~led;
  174. }
  175. void        F_key13_up()
  176. {
  177.                 beep_flag=0;
  178.                 beep_time=0x07d0;        //2秒
  179. }
  180. void        F_key14_up()
  181. {
  182. //          R_key_num=8;
  183. //          led=~led;
  184. }
  185. void        F_key15_up()
  186. {
  187. //          R_key_num=8;
  188. //          led=~led;
  189. }
  190. void        F_key16_up()
  191. {
  192. //          R_key_num=8;
  193. //          led=~led;
  194. }



  195. //按鍵按下總函數(shù)
  196. void        key_dn()
  197. {

  198.                 switch(R_key_num+1)
  199.              {                  


  200.                            case 1:       
  201.                                         F_key1_dn();                                 
  202.                                            break;
  203.                            case 2:       
  204.                                         F_key2_dn();                                 
  205.                                            break;
  206.                            case 3:       
  207.                                         F_key3_dn();                                 
  208.                                            break;
  209.                            case 4:       
  210.                                         F_key4_dn();                                 
  211.                                            break;
  212.                            case 5:       
  213.                                         F_key5_dn();                                 
  214.                                            break;
  215.                            case 6:       
  216.                                         F_key6_dn();                                 
  217.                                            break;
  218.                            case 7:       
  219.                                         F_key7_dn();                                 
  220.                                            break;
  221.                            case 8:       
  222.                                         F_key8_dn();                                 
  223.                                            break;
  224.                            case 9:       
  225.                                         F_key9_dn();                                 
  226.                                            break;
  227.                            case 10:       
  228.                                         F_key10_dn();                                 
  229.                                            break;
  230.                            case 11:       
  231.                                         F_key11_dn();                                 
  232.                                            break;
  233.                            case 12:       
  234.                                         F_key12_dn();                                 
  235.                                            break;
  236.                            case 13:       
  237.                                         F_key13_dn();                                 
  238.                                            break;
  239.                            case 14:       
  240.                                         F_key14_dn();                                 
  241.                                            break;
  242.                            case 15:       
  243.                                         F_key15_dn();                                 
  244.                                            break;
  245.                            case 16:       
  246.                                         F_key16_dn();                                 
  247.                                            break;


  248.                            default:       
  249.                      break;
  250.                 }
  251.        
  252. }
  253. //按鍵松開總函數(shù)
  254. void        key_up()
  255. {

  256.                 switch(R_key_num+1)
  257.              {                  


  258.                            case 1:       
  259.                                         F_key1_up();                                 
  260.                                            break;
  261.                            case 2:       
  262.                                         F_key2_up();                                 
  263.                                            break;
  264.                            case 3:       
  265.                                         F_key3_up();                                 
  266.                                            break;
  267.                            case 4:       
  268.                                         F_key4_up();                                 
  269.                                            break;
  270.                            case 5:       
  271.                                         F_key5_up();                                 
  272.                                            break;
  273.                            case 6:       
  274.                                         F_key6_up();                                 
  275.                                            break;
  276.                            case 7:       
  277.                                         F_key7_up();                                 
  278.                                            break;
  279.                            case 8:       
  280.                                         F_key8_up();                                 
  281.                                            break;
  282.                            case 9:       
  283.                                         F_key9_up();                                 
  284.                                            break;
  285.                            case 10:       
  286.                                         F_key10_up();                                 
  287.                                            break;
  288.                            case 11:       
  289.                                         F_key11_up();                                 
  290.                                            break;
  291.                            case 12:       
  292.                                         F_key12_up();                                 
  293.                                            break;
  294.                            case 13:       
  295.                                         F_key13_up();                                 
  296.                                            break;
  297.                            case 14:       
  298.                                         F_key14_up();                                 
  299.                                            break;
  300.                            case 15:       
  301.                                         F_key15_up();                                 
  302.                                            break;
  303.                            case 16:       
  304.                                         F_key16_up();                                 
  305.                                            break;


  306.                            default:       
  307.                      break;
  308.                 }
  309.        
  310. }

  311. void        Keyscan_task()
  312. {
  313.          u8                ar;
  314.      u8                ax;
  315.      u8                i;

  316.           D_ScanLineDec=D_ScanLineDec+1;
  317.           if(D_ScanLineDec==1)                                           //掃描第一條線
  318.           {
  319.                           ar=P0;
  320.                           ax=P0_key;
  321.                           ar=ar^ax;
  322.                           ar=ar|ax;                                                  //獲取按鍵值

  323.           }
  324.           if(D_ScanLineDec==2)                                   //掃描第二條線
  325.           {
  326.                           ar=P2;
  327.                           ax=P2_key;
  328.                           ar=ar^ax;
  329.                           ar=ar|ax;                                                 //獲取按鍵值
  330.           }



  331.           ax=R_key_value[D_ScanLineDec-1];                //跟變化的按鍵值比較
  332.           ax=ar-ax;
  333.           if(ax!=0)                                                                 //不等于0說按鍵有動作(按下或者松開)
  334.           {

  335.                 R_key_value[D_ScanLineDec-1]=ar;        //記錄當(dāng)前的按鍵值,然后進(jìn)行消抖
  336.                 R_key_douce=D_ESTTime;                            //設(shè)置消抖時間

  337.                 D_ScanLineDec=D_ScanLine;                    //重新更新掃描線,重新開始掃描

  338.           }
  339.           else
  340.           {
  341.                            if(R_key_douce==0)                                 //中斷消抖,,判斷消抖時間到了?
  342.                         {
  343.                                  ax=R_key_buf[D_ScanLineDec-1];                          //把按鍵變化后值拿出來
  344.                                  ar=R_key_value[D_ScanLineDec-1];                 //把變化中的按鍵值拿出來
  345.                                  ar=ar^ax;
  346.                                  if(ar!=0)                                                                //按鍵發(fā)生變化 ar
  347.                                  {
  348.                                                 ax=ar&ax;
  349.                                                 if(ax!=0)                                           //按鍵按下
  350.                                                 {
  351.                                                         for(i=0;i<8;i ++)                          
  352.                                                        
  353.                                                         {
  354.                                                                 ax=(ar>>i)&1;                           //取出具體是哪一位的按鍵有變化,一次只取一位
  355.                                                                 if(ax==1)
  356.                                                                 {
  357.                                                                         R_key_num=i;
  358.                                                                         ar=0x01<<i;
  359.                                                                         R_key_buf[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1]^ar;   //保存最終的按鍵值
  360.                                                                         R_key_value[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1];        //保存最終的按鍵變化值  
  361.                                                                         for(ar=1;ar<=D_ScanLineDec-1;ar++)
  362.                                                                         {
  363.                                                                                 R_key_num=R_key_num+8;
  364.                                                                         }
  365.                                                
  366.                                                                      key_dn();
  367.                                                                 }
  368.                                                         }



  369.                                                 }
  370.                                                 else            //按鍵松開原理同按鍵按下一樣
  371.                                                 {
  372.                                                                 for(i=0;i<8;i ++)
  373.                                                        
  374.                                                         {
  375.                                                                 ax=(ar>>i)&1;
  376.                                                                 if(ax==1)
  377.                                                                 {
  378.                                                                         R_key_num=i;
  379.                                                                         ar=0x01<<i;
  380.                                                                         R_key_buf[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1]^ar;   //保存最終的按鍵值
  381.                                                                         R_key_value[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1];          
  382.                                                                         for(ar=1;ar<=D_ScanLineDec-1;ar++)
  383.                                                                         {
  384.                                                                                 R_key_num=R_key_num+8;
  385.                                                                         }
  386.                                                                      key_up();
  387.                                                                 }
  388.                                                         }       
  389.                                                 }

  390.                                  }
  391.                                
  392.                                 else
  393.                                 {
  394.                                        
  395.                                 }        /////按鍵沒按下

  396.                         }                               
  397.                   
  398.                   
  399.           }

  400. }                                                

  401. void        F_Keyscan()
  402. {
  403.         D_ScanLineDec=0;


  404.         while(D_ScanLine-D_ScanLineDec)
  405.         {
  406.                 Keyscan_task();
  407.         }
  408. }
  409.           
  410. void        F_Key_buf_value_init()
  411. {
  412.     u8                i;
  413.         for(i=0;i<D_ScanLine;i ++)
  414.         {
  415.                 R_key_buf[i]=0xff;
  416.                 R_key_value[i]=0xff;                                                       
  417.         }
  418.                
  419. }
復(fù)制代碼

所有程序51hei打包下載:
STC8 實驗3 -按鍵.rar (92.31 KB, 下載次數(shù): 19)

評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:282095 發(fā)表于 2019-7-21 10:33 | 只看該作者
希望可以更簡單明了一些
回復(fù)

使用道具 舉報

板凳
ID:207882 發(fā)表于 2019-7-21 14:59 | 只看該作者
鵬博士PBs 發(fā)表于 2019-7-21 10:33
希望可以更簡單明了一些

程序上還可以在優(yōu)化一下,但這個按鍵思路跟常見的按鍵觸發(fā)方法比,我覺得是是比較好的,嘻嘻
回復(fù)

使用道具 舉報

地板
ID:253767 發(fā)表于 2019-7-22 07:10 | 只看該作者
謝謝分享!!!
回復(fù)

使用道具 舉報

5#
ID:138453 發(fā)表于 2019-7-22 08:38 | 只看該作者
NICE!!!!
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 毛片区 | 久久国产福利 | 国产成人一区二区三区 | 爱综合| 精品videossex高潮汇编 | 国产电影一区 | 久草在线免费资源 | 欧美久久久久久 | 久久久久久久久国产精品 | 99精品久久久 | 操人网站 | 国产精品久久久久久久久久久久 | 午夜91| 亚洲精品日韩在线观看 | 国产成人99久久亚洲综合精品 | 亚洲+变态+欧美+另类+精品 | 中文字幕三区 | 美日韩中文字幕 | 国产在线观| 国产一区二区在线播放 | 男女视频免费 | 亚洲天堂久久 | 国产美女在线免费观看 | 日韩精品免费看 | 嫩草懂你的影院入口 | 日韩欧美国产一区二区 | 欧美亚洲国产日韩 | 男人的天堂在线视频 | 天天躁日日躁性色aⅴ电影 免费在线观看成年人视频 国产欧美精品 | 日本亚洲一区 | 黄色永久免费 | 91麻豆产精品久久久久久夏晴子 | 九九热这里 | 亚洲精品一区在线 | 中文字幕第5页 | 99热首页| 国产在线1区 | 久久久www成人免费无遮挡大片 | 特一级毛片| 中文字幕亚洲一区 | 欧美日韩亚洲一区 |