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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1841|回復: 1
收起左側

單片機任意IO組合實現矩陣按鍵的程序

[復制鏈接]
ID:734940 發表于 2022-11-13 22:51 | 顯示全部樓層 |閱讀模式
單片機源程序如下:
  1. #include "STC32G.h"
  2. sbit C4 = P2^7;
  3. sbit C3 = P2^6;
  4. sbit C2 = P2^5;
  5. sbit C1 = P2^4;
  6. sbit R1 = P2^3;
  7. sbit R2 = P2^2;
  8. sbit R3 = P2^1;
  9. sbit R4 = P4^1;
  10. //理論可以使用任意io,不僅限P0、P1 ……
  11. unsigned char S16 = 0;
  12. bit        _1msPast = 0;
  13. bit busy;//串口忙
  14. bit keypressed = 0;//有鍵按下位
  15. //僅支持單按鍵,鍵在松開后執行操作。

  16. void KeyScan()
  17. {        //每個毫秒掃描一次,
  18.         unsigned char keys;//檢測到按下的鍵值
  19.         static unsigned char pressMscount,looseMscount,pressednum;//按下毫秒計數,松開毫秒計數,按下的鍵值
  20.         C1 = C2 = C3 = C4 = 1;
  21.         R1 = R2 = R3 = R4 = 0;
  22.         keys = !C1 * 1 + !C2 * 2 + !C3 * 3 + !C4 * 4;
  23.         C1 = C2 = C3 = C4 = 0;
  24.         R1 = R2 = R3 = R4 = 1;
  25.         keys += !R1 * 0 + !R2 * 4 + !R3 * 8 + !R4 * 12;
  26.         C1 = C2 = C3 = C4 = R1 = R2 = R3 = R4 = 0;
  27.         if(keys != 0)
  28.         {
  29.                 //當有鍵按下時,
  30.                 if(keypressed == 0)
  31.                 //如果鍵按下標志位為0,則說明突然有鍵按下,開始按下消抖計時
  32.                 {
  33.                         pressMscount += 1;
  34.                         while(pressMscount == 25)
  35.                         {
  36.                                 //計數達到25時確定有鍵按下,置keypressed位為1
  37.                                 keypressed = 1;
  38.                                 pressMscount = 0;
  39.                                 pressednum = keys;
  40.                         }
  41.                 }
  42.         }
  43.         else
  44.         {//如果無鍵按下,或者處于抖動狀態,則清除計數
  45.                 //如果剛剛處于有鍵按下狀態,則說明到達按鍵松開階段,鍵按下標志取消
  46.                 if(keypressed == 1)
  47.                 {
  48.                         looseMscount +=1;
  49.                         while(looseMscount == 25)
  50.                         {
  51.                                 //計數達到25時確定按鍵已松開,置keypressed位為0,發送剛剛按下的按鍵
  52.                                 keypressed = 0;
  53.                                 looseMscount = 0;
  54.                                 S16 = pressednum;
  55.                                 //松開抖動
  56.                         }
  57.                 }else if(keypressed == 0){
  58.                         //如果按下標志位為0,可能是處于無鍵按下狀態,或者處于按下抖動狀態
  59.                         pressMscount = 0;
  60.                 }
  61.         }
  62. }

  63. //定時器0設置
  64. void T0Set()
  65. {        
  66.         AUXR &= 0x7F;                //定時器時鐘12T模式
  67.         TMOD &= 0xF0;                //設置定時器模式
  68.         TL0 = 0x33;                //設置定時初始值
  69.         TH0 = 0xF5;                //設置定時初始值        //1毫秒@33.1776MHz
  70.         TF0 = 0;                //清除TF0標志
  71.         TR0 = 1;                        //啟動定時器
  72. }
  73. //在定時器0里進行毫秒累加
  74. void T0Action() interrupt 1
  75. {
  76.         _1msPast = 1;
  77. }
  78. //在main里監測到毫秒累加為1時執行動作,并歸零毫秒累加。
  79. void DealTimeInMain()
  80. {
  81.         while(_1msPast == 1)
  82.         {
  83.                 KeyScan();
  84.         _1msPast = 0;
  85.         }
  86. }
  87. //================================
  88. //發送字節
  89. void SendData(char dat)
  90. {
  91.     while (busy);           //Wait for the completion of the previous data is sent
  92.     ACC = dat;
  93.           if (P)                  //Set the parity bit according to P
  94.     {
  95.         TB8 = 1;            //Set parity bit to 1
  96.     }
  97.     else
  98.     {
  99.         TB8 = 0;            //Set parity bit to 0
  100.     }
  101.     busy = 1;
  102.     SBUF = ACC;             //Send data to UART buffer
  103. }

  104. char putchar(char c)
  105. {
  106.         SendData(c);
  107.         return c;
  108. }
  109. //串口1配置
  110. void UartInit()
  111. {
  112.         SCON = 0x50;        //8位數據,可變波特率
  113.         AUXR &= 0xBF;        //定時器時鐘12T模式
  114.         AUXR &= 0xFE;        //串口1選擇定時器1為波特率發生器
  115.         TMOD &= 0x0F;        //設置定時器模式
  116.         TL1 = 0xFA;                //設置定時初始值
  117.         TH1 = 0xFF;                //設置定時初始值
  118.         ET1 = 0;                //禁止定時器%d中斷
  119.         TR1 = 1;                //定時器1開始計時
  120.     busy = 0;
  121. }
  122. //串口通信
  123. void UartIsr() interrupt 4
  124. {
  125.         if (RI)
  126.         {
  127.                 RI = 0;             //Clear receive interrupt flag
  128.         }
  129.         if (TI)
  130.         {
  131.                 TI = 0;             //Clear transmit interrupt flag
  132.                 busy = 0;           //Clear transmit busy flag
  133.         }
  134. }
  135. void main()
  136. {
  137.         
  138.         EAXFR = 1;
  139.     P0M0 = 0x00;
  140.     P0M1 = 0x00;
  141.     P1M0 = 0x00;
  142.         P1M1 = 0x00;
  143.     P2M0 = 0x00;
  144.     P2M1 = 0x00;
  145.     P3M0 = 0x00;
  146.     P3M1 = 0x00;
  147.     P4M0 = 0x00;
  148.     P4M1 = 0x00;
  149.     P5M0 = 0x00;
  150.     P5M1 = 0x00;
  151.     P6M0 = 0x00;
  152.     P6M1 = 0x00;
  153.     P7M0 = 0x00;
  154.     P7M1 = 0x00;

  155.     UartInit();

  156.         T0Set();
  157. //        IT0 = 1;
  158.         ET0 = 1;                           //使能定時器0中斷
  159.     ES = 1;                                //使能串口1中斷
  160.     EA = 1;                                //使能總中斷
  161.         
  162.     while (1)
  163.     {
  164.                 DealTimeInMain();
  165.                 while(S16!=0)
  166.                 {//檢測到按鍵,執行動作
  167.                         printf("S%d被按下\r\n",S16);
  168.                         S16=0;
  169.                 }
  170.         }
  171. }
復制代碼

STC32G開發板和矩陣按鍵模塊.jpg

此代碼可以直接用于STC32G屠龍刀系列,波特率33.1776,C1234 R4321分別接:
C4 → P2^7;
C3 → P2^6;
C2 → P2^5;
C1 → P2^4;
R1 → P2^3;
R2 → P2^2;
R3 → P2^1;
R4 → P4^1;

按下S1-S16,然后松開會向串口返回按下的值,僅支持單鍵按下,多鍵會返回錯誤的值。不支持長按。
2.png

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:1042619 發表于 2022-11-14 11:42 | 顯示全部樓層
            感謝樓主精彩分享!另外從 STC-ISP V6.90T 以上版本的 ISP燒錄/輔助開發工具包一體化軟件的增加了I/O口配置小工具、增加將程序最小化到系統托盤區,提升幸福感小工具越來越多了.
JPG.3.png
jpg.4.jpg
JPG.1.png
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久999成人| 国产精品成人一区二区三区 | 久久久久久久一区二区三区 | 欧美激情视频一区二区三区免费 | a级大片免费观看 | 欧美成人一区二区 | 天天躁日日躁狠狠的躁天龙影院 | 国产一区| 国产精品久久午夜夜伦鲁鲁 | 欧美一级二级在线观看 | 久久久久久国产精品久久 | 日韩精品一区二区三区免费视频 | 日韩一区二区三区在线视频 | 欧美日韩亚洲国产 | 国产激情网站 | 国产一区不卡 | 日本视频一区二区 | 69福利影院 | 97在线观视频免费观看 | 美女高潮网站 | 日本精品久久久久 | 亚洲一区不卡 | 亚洲一区精品在线 | 成人精品毛片国产亚洲av十九禁 | 国产福利在线视频 | 精品无码三级在线观看视频 | 成人在线视频免费观看 | 91麻豆久久久 | 蜜桃av人人夜夜澡人人爽 | 龙珠z在线观看 | 欧美成人激情 | 免费亚洲成人 | 二区在线观看 | 国产成人av一区二区三区 | 亚洲国产成人精品女人久久久野战 | 成人依人| 国产精品成人一区二区三区 | 羞羞视频在线观看免费观看 | 日韩网站在线观看 | 国产黄色在线观看 | 久久精品免费 |