MCU周辺マトリックスキーボードのライン反転方式識別の原理と例
1。概要
この記事では主に、マイコンが 4X4 マトリックス キーボードからの命令をどのように受け取り、対応するフィードバックを行うかを紹介します。主にマトリックスキーボードライン反転法の識別原理と実際の操作を紹介します。
2. マトリックスキーボードの行反転認識の原理
2.1. マトリックスキーボードハードウェアの配線原理
マトリックス キーボードのハードウェア配線方法は多数ありますが、一般的に使用されるマトリックス配線は次のとおりです。
4X4マトリクスキーボードは4行4列で構成されており、行と列は2層の金属線フィルムで構成され、中央には絶縁層があり、各キーの位置には開口部があります。ある位置を押すと、行フィルムシートと列フィルムシートが密着し、この時に電流が流れます。導電電流の行位置と列位置を検出してボタンが押されたと判断します。
2.2. ライン反転認識の原理
1. ライン反転認識の原理の紹介
行反転認識の設計は非常に巧妙で、コードの複雑さと冗長性が簡素化されています。最初に列番号を識別し、次に行番号を識別し、2 回の識別の後にキーの位置を決定するため、ライン反転識別と呼ばれます。
ライン反転を特定する手順は次のとおりです。
- 列認識モードを設定する
- 行の下位 4 ビットと列の上位 4 ビットは、行では 0、列では 1 に設定されます。
0xf0
- 行の下位 4 ビットと列の上位 4 ビットは、行では 0、列では 1 に設定されます。
- 列番号を識別する
- ボタンを押すと、特定の列の値が 0 に変わるので、対応する列番号を取得できます。たとえば、最初の列 1110 を押します。
- セットライン認識モードを反転する
- 行の下位 4 ビットと列の上位 4 ビットは、行では 1、列では 0 に設定されます。16 進値は次のとおりです。
0x0f
- 行の下位 4 ビットと列の上位 4 ビットは、行では 1、列では 0 に設定されます。16 進値は次のとおりです。
- 行番号を特定する
- ボタンを押すと、ある行の値が0になるので、例えば最初の行1110を押すと、対応する行番号を取得できます。
- 行番号 + 列番号 = キー番号
- 行番号と列番号の OR で 8 桁のバイナリ値を取得し、それを 16 進数に変換して、キーに対応するキー コードを取得します。
2. ライン反転認識の例
上記でライン反転認識の原理を紹介した後、例を通してその原理を実際の結果に変換する方法を学びましょう. この例ではボタン 1 を例として使用しています. 他のボタン コード値の計算方法は同じ。
ボタン No.1 のキーコード計算例
上図の 4X4 配線図を基にボタン No.1 のキーコードを計算しKEYIN1~KEYIN4
ますKEYOUT1~KEYOUT4
。
-
列認識モードを設定する
- すべてを低レベル モードに設定
KEYIN1~KEYIN4
、バイナリは0000
、KEYOUT1~KEYOUT4
すべてを高レベル モードに設定、バイナリは1111
、列は上位 4 ビット、動作は下位 4 ビットであるため、結合された 8 ビット バイナリは次のようになります。1111 0000
- すべてを低レベル モードに設定
-
列番号を識別する
- ボタン No. 1 を押します。ボタン No. 1 の配線は最初の列です。列の 2 進数は行の 2 進
1110
数です0000
。結合された 8 ビット 2 進数は次のようになります。1110 0000
- ボタン No. 1 を押します。ボタン No. 1 の配線は最初の列です。列の 2 進数は行の 2 進
-
セットライン認識モードを反転する
KEYIN1~KEYIN4
すべてを高レベル モードに設定、バイナリを意味1111
、KEYOUT1~KEYOUT4
すべてを低レベル モードに設定、バイナリを意味0000
、列は上位 4 ビット、動作は下位 4 ビットであるため、結合された 8 ビット バイナリは次のようになります。0000 1111
-
行番号を特定する
- ボタン No.1 を押します。ボタン No.1 の配線が 1 行目です。行の 2 進数は
1110
列の 2 進数です0000
。結合された 8 ビット 2 進数は次のようになります。0000 1110
- ボタン No.1 を押します。ボタン No.1 の配線が 1 行目です。行の 2 進数は
-
行番号 + 列番号 = キー番号
- 行番号と列番号
或
(1110 0000 | 0000 1110) を計算して 8 桁の 2 進値を取得し1110 1110
、これを 16 進数に変換します。0xEE
- 行番号と列番号
3. マトリックスキーボードのLEDライト点灯実験
実験の目標
プログラムではキーボードのキーのコード値を受け取り、コード値を判定してLEDライトの点灯・消灯を制御します。
ハードウェア回路原理
- LEDライトのプラス極はVCCの20番ピンに接続され、マイナス極はP3.7の11番ピンに接続されています。
- キーボードケーブルには番号が付いており、小さい順に1番がP1.0の12番ピン、8番がP1.7の19番ピンに対応します。
コアコードの紹介
KEY()
この関数の機能は、行反転メソッドを通じてキーのキー値を識別し、プログラムを通じて対応するアクションを実行することです。この関数は、上記のライン反転原理を実装します。
/*
函数名:线翻转法读取键盘按键值
调 用:? = Key (void);
参 数:无
返回值:0~0xff
结 果:连接Px接口的键盘读出返回值
备 注:
*/
unsigned char Key (void){
//键盘处理函数
unsigned char a,b,c;//定义3个变量
//设置列识别模式:行为低4位,列为高4位,将行全部设置为0,列全部设置为1,二进制为:11110000,十六进制值为 0xf0
KEY = 0xf0;
if(KEY != 0xf0){
//查寻键盘口的值是否变化
DELAY_MS (20);//延时20毫秒,去除按键抖动
if(KEY != 0xf0){
//有键按下处理
a = KEY;//键值放入寄存器a
}
//翻转设置行识别模式:行为低4位,列为高4位,将行全部设置为1,列全部设置为0,二进制为:00001111,十六进制值为 0x0f
KEY = 0x0f;
c = KEY;//将第二次取得值放入寄存器c
a = a|c;//将两个数据相或
switch(a){
//对比数据值
case 0xee: b = 1; break;//对比得 到的键值给b一个应用数据
case 0xed: b = 2; break;
case 0xeb: b = 3; break;
case 0xe7: b = 4; break;
case 0xde: b = 5; break;
case 0xdd: b = 6; break;
case 0xdb: b = 7; break;
case 0xd7: b = 8; break;
case 0xbe: b = 9; break;
case 0xbd: b = 10; break;
case 0xbb: b = 11; break;
case 0xb7: b = 12; break;
case 0x7e: b = 13; break;
case 0x7d: b = 14; break;
case 0x7b: b = 15; break;
case 0x77: b = 16; break;
default: b = 0; break;//键值错误处理
}
}
return (b);//将b作为返回值
}
完全なコード
/*
程序名:线翻转法操作矩阵键盘
编写人:bruce
编写时间:2023年12月
硬件支持:STC12C2052AD系列
接口说明:
修改日志:
NO.1-
*/
#include <STC12C2052AD.H> //STC12Cx052或STC12Cx052AD系列单片机头文件
sbit LED = P3 ^ 7;
#define KEY P1
/*
函数名:毫秒级CPU延时函数
调 用:DELAY_MS (?);
参 数:1~65535(参数不可为0)
返回值:无
结 果:占用CPU方式延时与参数数值相同的毫秒时间
备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
*/
void DELAY_MS (unsigned int a){
unsigned int i;
while( a-- != 0){
for(i = 0; i < 600; i++);
}
}
/*
函数名:线翻转法读取键盘按键值
调 用:? = Key (void);
参 数:无
返回值:0~0xff
结 果:连接Px接口的键盘读出返回值
备 注:
*/
unsigned char Key (void){
//键盘处理函数
unsigned char a,b,c;//定义3个变量
//设置列识别模式:行为低4位,列为高4位,将行全部设置为0,列全部设置为1,二进制为:11110000,十六进制值为 0xf0
KEY = 0xf0;
if(KEY != 0xf0){
//查寻键盘口的值是否变化
DELAY_MS (20);//延时20毫秒,去除按键抖动
if(KEY != 0xf0){
//有键按下处理
a = KEY;//键值放入寄存器a
}
//翻转设置行识别模式:行为低4位,列为高4位,将行全部设置为1,列全部设置为0,二进制为:00001111,十六进制值为 0x0f
KEY = 0x0f;
c = KEY;//将第二次取得值放入寄存器c
a = a|c;//将两个数据相或
switch(a){
//对比数据值
case 0xee: b = 1; break;//对比得 到的键值给b一个应用数据
case 0xed: b = 2; break;
case 0xeb: b = 3; break;
case 0xe7: b = 4; break;
case 0xde: b = 5; break;
case 0xdd: b = 6; break;
case 0xdb: b = 7; break;
case 0xd7: b = 8; break;
case 0xbe: b = 9; break;
case 0xbd: b = 10; break;
case 0xbb: b = 11; break;
case 0xb7: b = 12; break;
case 0x7e: b = 13; break;
case 0x7d: b = 14; break;
case 0x7b: b = 15; break;
case 0x77: b = 16; break;
default: b = 0; break;//键值错误处理
}
}
return (b);//将b作为返回值
}
void main (void){
//主程序
while(1){
if(Key() == 1){
LED = 0; //取LED相反状态
}
if(Key() == 2){
LED = 1; //取LED相反状态
}
}
}