日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【51单片机快速入门指南】2.3:GPIO读取矩阵键盘 8个IO读16键

發(fā)布時間:2023/12/9 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【51单片机快速入门指南】2.3:GPIO读取矩阵键盘 8个IO读16键 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 硬知識
    • 矩陣鍵盤介紹
  • 測試程序
    • Key_Board.c
    • Key_Board.h
    • main.c
  • 實驗現(xiàn)象

普中51-單核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬知識

選自《普中51單片機開發(fā)攻略_V1.2》

矩陣鍵盤介紹

???????獨立按鍵與單片機連接時,每一個按鍵都需要單片機的一個 I/O 口,若某單片機系統(tǒng)需較多按鍵,如果用獨立按鍵便會占用過多的 I/O 口資源。單片機系統(tǒng)中 I/O 口資源往往比較寶貴,當(dāng)用到多個按鍵時為了減少 I/O 口引腳,便引入了矩陣按鍵。
???????以 4x4 矩陣鍵盤為例講解其工作原理和檢測方法。開發(fā)板上將 16 個按 鍵排成 4 行 4 列,第一行將每個按鍵的一端連接在一起構(gòu)成行線,第一列將每個按鍵的另一端連接在一起構(gòu)成列線,這樣便一共有 4 行 4 列共 8 根線,我們將這 8 根線連接到單片機的 8 個 I/O 口上,通過程序掃描鍵盤就可檢測 16 個 鍵。用這種方法我們也可實現(xiàn) 3 行 3 列 9 個鍵、 5 行 5 列 25 個鍵、 6 行 6 列 36 個鍵甚至更多。
???????無論是獨立鍵盤還是矩陣鍵盤,單片機檢測其是否被按下的依據(jù)都是一樣的,也就是檢測與該鍵對應(yīng)的 I/O 口是否為低電平。獨立鍵盤有一端固定為低電平,此種方式編程比較簡單。 而矩陣鍵盤兩端都與單片機 I/O 口相連,因此 在檢測時需編程通過單片機 I/O 口送出低電平。檢測方法有多種,最常用的是行列掃描和線翻轉(zhuǎn)法。
???????行列掃描法檢測時,先送一列為低電平,其余幾列全為高電平(此時我們確定了列數(shù)),然后立即輪流檢測一次各行是否有低電平,若檢測到某一行為低電平(這時我們又確定了行數(shù)),則我們便可確認(rèn)當(dāng)前被按下的鍵是哪一行哪一列的,用同樣方法輪流送各列一次低電平,再輪流檢測一次各行是否變?yōu)榈碗娖?#xff0c; 這樣即可檢測完所有的按鍵,當(dāng)有鍵被按下時便可判斷出按下的鍵是哪一個鍵。 當(dāng)然我們也可以將行線置低電平,掃描列是否有低電平。從而達到整個鍵盤的檢測。
???????線翻轉(zhuǎn)法,就是使所有行線為低電平時,檢測所有列線是否有低電平,如果有,就記錄列線值;然后再翻轉(zhuǎn),使所有列線都為低電平,檢測所有行線的值, 由于有按鍵按下,行線的值也會有變化,記錄行線的值。從而就可以檢測到全部按鍵。

測試程序

本程序修改自官方例程《9-矩陣按鍵實驗》

stdint.h見【51單片機快速入門指南】1:基礎(chǔ)知識和工程創(chuàng)建

Key_Board.c

#include <REGX52.H> #include "intrins.h" #include "stdint.h"#define KEY_MATRIX_PORT P1 //使用宏定義矩陣按鍵控制口 #define KEY_BOARD_WHILE_FLAG 0void Key_Board_Delay() //20ms @11.0592MHz {unsigned char i, j;i = 36;j = 217;do{while (--j);} while (--i); }/******************************************************************************* * 函 數(shù) 名 : key_matrix_ranks_scan * 函數(shù)功能 : 使用行列式掃描方法,檢測矩陣按鍵是否按下,按下則返回對應(yīng)鍵值 * 輸 入 : 無 * 輸 出 : key_value:1-16,對應(yīng)S1-S16鍵,0:按鍵未按下 *******************************************************************************/ uint8_t key_matrix_ranks_scan(void) {uint8_t key_value=0;KEY_MATRIX_PORT=0xf7;//給第一列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xf7)//判斷第一列按鍵是否按下{if(key_value)Key_Board_Delay();//消抖switch(KEY_MATRIX_PORT)//保存第一列按鍵按下后的鍵值 {case 0x77: key_value=1;break;case 0xb7: key_value=5;break;case 0xd7: key_value=9;break;case 0xe7: key_value=13;break;}} #if KEY_BOARD_WHILE_FLAGwhile(KEY_MATRIX_PORT!=0xf7);//等待按鍵松開 #endif KEY_MATRIX_PORT=0xfb;//給第二列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xfb)//判斷第二列按鍵是否按下{if(key_value)Key_Board_Delay();//消抖switch(KEY_MATRIX_PORT)//保存第二列按鍵按下后的鍵值 {case 0x7b: key_value=2;break;case 0xbb: key_value=6;break;case 0xdb: key_value=10;break;case 0xeb: key_value=14;break;}} #if KEY_BOARD_WHILE_FLAGwhile(KEY_MATRIX_PORT!=0xfb);//等待按鍵松開 #endif KEY_MATRIX_PORT=0xfd;//給第三列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xfd)//判斷第三列按鍵是否按下{if(key_value)Key_Board_Delay();//消抖switch(KEY_MATRIX_PORT)//保存第三列按鍵按下后的鍵值 {case 0x7d: key_value=3;break;case 0xbd: key_value=7;break;case 0xdd: key_value=11;break;case 0xed: key_value=15;break;}} #if KEY_BOARD_WHILE_FLAGwhile(KEY_MATRIX_PORT!=0xfd);//等待按鍵松開 #endif KEY_MATRIX_PORT=0xfe;//給第四列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xfe)//判斷第四列按鍵是否按下{if(key_value)Key_Board_Delay();//消抖switch(KEY_MATRIX_PORT)//保存第四列按鍵按下后的鍵值 {case 0x7e: key_value=4;break;case 0xbe: key_value=8;break;case 0xde: key_value=12;break;case 0xee: key_value=16;break;}} #if KEY_BOARD_WHILE_FLAGwhile(KEY_MATRIX_PORT!=0xfe);//等待按鍵松開 #endif return key_value; }/******************************************************************************* * 函 數(shù) 名 : key_matrix_flip_scan * 函數(shù)功能 : 使用線翻轉(zhuǎn)掃描方法,檢測矩陣按鍵是否按下,按下則返回對應(yīng)鍵值 * 輸 入 : 無 * 輸 出 : key_value:1-16,對應(yīng)S1-S16鍵,0:按鍵未按下 *******************************************************************************/ uint8_t key_matrix_flip_scan(void) {static uint8_t key_value=0;KEY_MATRIX_PORT=0x0f;//給所有行賦值0,列全為1if(KEY_MATRIX_PORT!=0x0f)//判斷按鍵是否按下{if(key_value)Key_Board_Delay();//消抖if(KEY_MATRIX_PORT!=0x0f){//測試列KEY_MATRIX_PORT=0x0f;switch(KEY_MATRIX_PORT)//保存行為0,按鍵按下后的列值 {case 0x07: key_value=1;break;case 0x0b: key_value=2;break;case 0x0d: key_value=3;break;case 0x0e: key_value=4;break;}//測試行KEY_MATRIX_PORT=0xf0;switch(KEY_MATRIX_PORT)//保存列為0,按鍵按下后的鍵值 {case 0x70: key_value=key_value;break;case 0xb0: key_value=key_value+4;break;case 0xd0: key_value=key_value+8;break;case 0xe0: key_value=key_value+12;break;} #if KEY_BOARD_WHILE_FLAGwhile(KEY_MATRIX_PORT!=0xf0);//等待按鍵松開 #endif}}elsekey_value=0; return key_value; }

Key_Board.h

#ifndef KEY_BOARD_H_ #define KEY_BOARD_H_#include "stdint.h"uint8_t key_matrix_ranks_scan(void); uint8_t key_matrix_flip_scan(void);#endif

main.c

#include <REGX52.H> #include "intrins.h" #include "stdint.h" #include "Key_Board.h"sbit D1 = P2^0;void Delay63ms() //@11.0592MHz {unsigned char i, j;i = 113;j = 242;do{while (--j);} while (--i); }void main(void) { uint8_t Key_Flag = 0;uint8_t i = 0;while(1){Key_Flag = key_matrix_flip_scan(); if(Key_Flag){D1 = 1;for(i = 0; i < Key_Flag; ++i)Delay63ms();D1 = 0;for(i = 0; i < Key_Flag; ++i)Delay63ms();}elseD1 = 1;} }

實驗現(xiàn)象

按住鍵盤上不同的按鍵,D0將以不同的頻率閃爍。

總結(jié)

以上是生活随笔為你收集整理的【51单片机快速入门指南】2.3:GPIO读取矩阵键盘 8个IO读16键的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。