欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9788|回復: 8
打印 上一主題 下一主題
收起左側

求助一個4*4鍵盤掃描程序

[復制鏈接]
跳轉到指定樓層
樓主
10黑幣
我想用51單片機實現4*4鍵盤掃描功能,鍵盤通常有幾種可能,一種是抖動,一種是按下,一種是抬起,一種是長按(分辨3000毫秒時長為長按),我們只要實現按下就發送指令到串口,在電腦上通過串口助手可以獲取單片機發來的指令,指令形式按照“0-9*ABCD”分別代表16個鍵。

最佳答案

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

使用道具 舉報

沙發
ID:213173 發表于 2017-11-3 14:09 | 只看該作者
1606188581 發表于 2017-11-5 11:43
有沒有電路圖呢?我是小白,麻煩簡單畫個圖紙也行


回復

使用道具 舉報

板凳
ID:245536 發表于 2017-11-3 15:23 | 只看該作者
由于我的黑幣太少無法懸賞太多,我可以用現金方式懸賞,有意義留言即可
回復

使用道具 舉報

地板
ID:82765 發表于 2017-11-3 20:49 | 只看該作者
提示: 作者被禁止或刪除 內容自動屏蔽
回復

使用道具 舉報

5#
ID:213173 發表于 2017-11-4 07:20 | 只看該作者
送你一個示例,4*4矩陣鍵盤接在P2(只能接P1或P2,不能接P3,否則與串口沖突。如果接P0要加上拉電阻)。
#include <AT89X52.H>
#define uint unsigned int                 //宏定義無符號整型數據
#define uchar unsigned char         //宏定義無符號字符型數據
uchar key=0xff;                                        //定義鍵值全局變量
bit flag=0;                                                //定義發送標志

void keyscan()                                        //按鍵掃描程序
{
        static bit sign=0;                        //按鍵有效標志
        static uint count=0;                //消抖計數變量                       
        uchar num=0;                                //臨時變量
        P2=0xf0;                                                //賦值P2 1111 0000
        if((P2!=0xf0)&&(sign==0))        //檢測按鍵有效
        {
                count++;                                //消抖計數
                if(count>=500)                        //100~1000,根據主循環周期調整約10~20ms
                {                       
                        sign=1;                                //按鍵有效標志置1
                        num=P2;                                //保存P2值xxxx 0000,x為0或1
                        num|=0x0f;                        //保存num按位或0x0f值xxxx 1111
                        P2=num;                                //賦值P2 xxxx 1111
                        num=P2;                                //保存P2值xxxx xxxx
                        switch(num)
                        {
                                case 0xee: key=0x00; break;
                                case 0xde: key=0x01; break;
                                case 0xbe: key=0x02; break;
                                case 0x7e: key=0x03; break;
                                case 0xed: key=0x04; break;
                                case 0xdd: key=0x05; break;
                                case 0xbd: key=0x06; break;
                                case 0x7d: key=0x07; break;
                                case 0xeb: key=0x08; break;
                                case 0xdb: key=0x09; break;
                                case 0xbb: key=0x0a; break;
                                case 0x7b: key=0x0b; break;
                                case 0xe7: key=0x0c; break;
                                case 0xd7: key=0x0d; break;
                                case 0xb7: key=0x0e; break;
                                case 0x77: key=0x0f; break;
                        }
                        flag=1;
                }
        }
        else                                                //鍵抬起
        {
                sign=0;                                        //按鍵有效標志清0
                count=0;                                //消抖計數清0
        }
}
void main()                                                //主函數
{
        TMOD=0x20;//定時器1方式2(8位重載)
        TH1=0xfd; //波特率9600
        TL1=0xfd; //波特率9600
        TR1=1;        //開定時器1
        SM0=0;        //設置串口方式1(8位UART波特率可變)
        SM1=1;        //設置串口方式1(8位UART波特率可變)
        while(1)
        {
                keyscan();                        //按鍵掃描程序
                if(flag==1)                        //發送標志為1
                {
                        flag = 0;                //發送標志清0
                        SBUF = key;                //發送鍵值數據
                        while(!TI)                //等待發送中斷請求標志位為1
                        TI=0;                                //發送中斷請求標志位清0
                }
        }
}
回復

使用道具 舉報

6#
ID:111634 發表于 2017-11-4 21:21 | 只看該作者
本帖最后由 zl2168 于 2017-11-4 21:32 編輯

介紹你幾個短按/長按處理的案例
Proteus仿真一下,確認有效。

實例96  能預置初值的倒計時秒表
實例96 能設置初值的倒計時秒表.rar (40 KB, 下載次數: 8)

實例91  具有校正功能的時鐘1302LCD1602顯示)
實例91 帶校正時鐘1302(LCD1602顯示).rar (52.68 KB, 下載次數: 5)

實例93  具有校正功能的時鐘1302LED數碼管顯示)
實例93 帶校正時分秒的時鐘1302(6位LED數碼管顯示).rar (732.75 KB, 下載次數: 4)

以上摘自張志良編著《80C51單片機仿真設計實例教程——基于Keil CProteus》清華大學出版社ISBN 978-7-302-41682-1內有常用的單片機應用100案例,用于仿真實驗操作,電路與程序真實可靠可信可行。仿真電路和Hex文件能在清華出版社網站免費下載,程序源代碼只能到書上看了。到圖書館借,或到新華書店翻閱,或到網上書店打折購買。

99.9秒秒表.jpg (128.43 KB, 下載次數: 94)

99.9秒秒表.jpg

實例95 99.9秒秒表.rar

38.86 KB, 下載次數: 3

回復

使用道具 舉報

7#
ID:245536 發表于 2017-11-5 11:43 | 只看該作者
wulin 發表于 2017-11-4 07:20
送你一個示例,4*4矩陣鍵盤接在P2(只能接P1或P2,不能接P3,否則與串口沖突。如果接P0要加上拉電阻)。
#in ...

有沒有電路圖呢?我是小白,麻煩簡單畫個圖紙也行
回復

使用道具 舉報

8#
ID:243738 發表于 2017-11-5 12:42 | 只看該作者
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define GPIO_DIG P0
  5. #define GPIO_KEY P1

  6. uchar code DIG_CODE[17]=
  7. {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  8. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  9. //數碼管的顯示碼
  10. uchar KeyValue;
  11. //用來存放讀取到的按下的鍵值
  12. void Delay10ms();
  13. //延時10ms
  14. void KeyDown();
  15. //按鍵函數
  16. void main(void)
  17. {
  18.         while(1)
  19.         {
  20.                 KeyDown();
  21.                 GPIO_DIG=~DIG_CODE[KeyValue];
  22.                 //數碼管顯示按鍵值
  23.         }                               
  24. }
  25. void KeyDown(void)
  26. {
  27.         char a=0;
  28.         GPIO_KEY=0x0f;//P1高四位低電平0000,低四位高電平1111
  29.         if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
  30.         {
  31.         Delay10ms();//延時10ms消抖
  32.                 if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
  33.                 {
  34.                         GPIO_KEY=0x0f;//測試列 00001111
  35.                                 switch(GPIO_KEY)
  36.                                 {
  37.                                         case(0x07): KeyValue=0;break;//00000111,第一列有按鍵按下  
  38.                                         case(0x0b): KeyValue=1;break;//00001011,第二列有按鍵按下
  39.                                         case(0x0d): KeyValue=2;break;//00001101,第三列有按鍵按下
  40.                                         case(0x0e): KeyValue=3;break;//00001110,第四列有按鍵按下
  41.                                 }
  42.                         GPIO_KEY=0xf0;//測試行 11110000
  43.                                 switch(GPIO_KEY)
  44.                                 {
  45.                                         case(0x70): KeyValue=KeyValue;break;//01110000,第一行有按鍵按下
  46.                                         case(0xb0): KeyValue=KeyValue+4;break;//10110000,第二行有按鍵按下
  47.                                         case(0xd0): KeyValue=KeyValue+8;break;//11010000,第三行有按鍵按下
  48.                                         case(0xe0): KeyValue=KeyValue+12;break;//11100000,第四行有按鍵按下
  49.                                 }//得到相應的鍵值
  50.                         while((a<50)&&(GPIO_KEY!=0xf0))//按鍵松手檢測
  51.                                 {
  52.                                 Delay10ms();
  53.                                 a++;
  54.                                 }
  55.                         }
  56.         }
  57. }

  58. void Delay10ms(void)   //誤差 0us
  59. {
  60.     uchar a,b,c;
  61.     for(c=1;c>0;c--)
  62.         for(b=38;b>0;b--)
  63.             for(a=130;a>0;a--);
  64. }


  65. /*逐行掃描:高四位輪流輸出低電平來對矩陣鍵盤
  66. 進行逐行掃描,當低四位接收到的數據不全為1時
  67. 說明有按鍵按下,然后通過接收到的數據是哪一
  68. 位為0來判斷哪一個按鍵被按下*/
  69. /*行列掃描:我們可以通過高四位全部輸出低電平,
  70. 低四位輸出高電平。當接收到的數據,低四位不全為高電平時,
  71. 說明有按鍵按下,然后通過接收的數據值,判斷是哪一列有
  72. 按鍵按下,然后再反過來,高四位輸出高電平,第四位輸出低電平,
  73. 然后根據接收到的高四位的值判斷是哪一行有按鍵按下,這樣就能夠
  74. 確定是哪一個按鍵按下了。*/
復制代碼
回復

使用道具 舉報

9#
ID:245536 發表于 2017-11-5 13:43 | 只看該作者

電路圖有嗎?我不太在行
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表