MCUペリフェラルマトリックスキーボードの行と列のスキャン識別の原理と例

MCUペリフェラルマトリックスキーボードの行と列のスキャン識別の原理と例

1。概要

この記事では、行と列のスキャンを通じてマトリックス キーボードのキーを識別し、プログラムを通じて対応する操作を実行するマイクロコントローラーを紹介します。

2.行と列の走査認識の原理

2.1.独立キー認識の原理

マトリックス キーが必要な理由
独立したキーは操作が簡単ですが、数が多いとマイコンの IO ポートを占有し、キーの数が制限され、より多くのキーが必要なシナリオに対応できなくなります。多数のキーがあり、占有されている IO ポートはほとんどありません。

なぜ独立したキーを導入するのですか
? なぜ直接マトリックス キーを導入せず、最初に独立したキーの動作原理を紹介しますか? これは、マトリックス キーボードが独立したキーの数をアップグレードしたものであるためです。マトリックス キーボードの動作原理は変わっていません。独立したキーの動作原理は依然として残っています。

独立したボタンの仕組み

  • ボタンをマイクロコントローラーに接続すると、ボタンを通じて LED ライトのオン/オフを制御できます。
  • - その動作原理は、ボタンの一端をマイクロコントローラーのIOポートに接続し、もう一端をGND端に接続することです。
  • ボタンを押すと、ボタンに接続されているIOポートとGNDが接続され、ハイレベルがローレベルになります。
  • IOポートのローレベルを検出するとLEDが点灯します。
  • ボタンを放すと、IO ポートが高レベルに戻り、LED ライトが消えます。

複数の独立したボタンの動作原理
LED ライトを制御する独立したボタンの原理を習得したら、複数の独立したボタンをワイヤで並列に接続して GND に接続し、ボタンの他​​端を各 IO ポートに接続することができます。マイクロコントローラーの独立したキーの列を形成します。

  • マイクロコントローラーのIOポートに接続されている各ボタンの名前を定義します。
  • ボタンを押すと、対応するIOポートのピンがGNDに接続され、ハイレベルがローレベルに変化します。
  • ローレベルピンに対応するボタンを検出し、プログラムロジックを通じて対応する動作を実行します。

ここに画像の説明を挿入します

2.2. 独立したボタンアップグレードマトリックスボタン

独立したキーの 1 列では不十分な場合は、複数の列を追加できます。ただし、マイクロコントローラーの IO ポートは限られているため、それ以上のボタンを挿入することはできません。このとき、マトリックス配線を使用して独立したキーを複数列接続し、行と列のマトリックス キーボードを形成できます。

行と列のスキャンの動作原理
たとえば、下の図は、KEYIN1~KEYIN4行とKEYOUT1~KEYOUT4列を備えた 4X4 マトリックス キーボードを示しています。

  • 最初の列の行スキャン: 最初の列を GND に接続しKEYIN1~KEYIN4、その行をマイクロコントローラーの 4 つの IO ポートに接続すると、上の複数の独立したボタンが独立したボタン シーンの列を形成します。ボタンが押されると、最初の列が列の行 1 ~ 4 のキーの高レベルと低レベル。
  • 2 列目の行スキャン: 2 列目を GND に接続し、KEYIN1~KEYIN4その行をマイコンの 4 つの IO ポートに接続し、ボタンを押すと 2 列目の 1 行目から 4 行目の High および Low レベルがスキャンされます。
  • 3 列目の行スキャン: 3 列目を GND に接続し、KEYIN1~KEYIN4行をマイコンの 4 つの IO ポートに接続し、ボタンを押すと 3 列目の 1 行目から 4 行目の High および Low レベルをスキャンします。 。
  • 4 列目の行スキャン: 3 列目を GND に接続し、KEYIN1~KEYIN4その行をマイコンの 4 つの IO ポートに接続し、ボタンを押すと 4 列目の 1 行目から 4 行目の High レベルと Low レベルをスキャンします。

ここに画像の説明を挿入します
行および行スキャン ソフトウェアの実装原理
マトリックス キーボードの行および行スキャンの動作原理を理解した後、プログラムを使用してキーを識別するための行および行スキャンを実現できます。

  • 最初の列をスキャン: 最初の列をKEYOUT1マイクロコントローラーのピンに接続し、ロー レベルに設定すると、ハードウェア回路をシミュレートして GND に接続できます。KEYIN1~KEYIN4行をマイクロコントローラーの 4 つの IO ポートに接続し、次のように設定します。押すと1号按键1行目が1列目に接続され、1行目のハイレベルがローレベルになり、この時点で押下が認識されます1号按键
  • 2 番目の列をスキャンします: KEYOUT22 番目の列をマイクロコントローラーのピンに接続し、ロー レベルに設定します。KEYIN1~KEYIN4行をマイクロコントローラーの 4 つの IO ポートに接続し、ハイ レベルに設定します。押すと、5号按键最初の行が接続されます。 2列目を通過すると、1行目のハイレベルがローレベルに変わり、この時点でプレスが認識できます5号按键
  • 3 列目をスキャン: KEYOUT33 列目をマイクロコントローラーのピンに接続し、ロー レベルに設定します。KEYIN1~KEYIN4行をマイクロコントローラーの 4 つの IO ポートに接続し、ハイ レベルに設定します。押すと、9号按键最初の行が接続されます。 3列目を通過すると、1行目のハイレベルがローレベルに変わり、この時点でプレスが認識できます9号按键
  • 4 列目をスキャン: KEYOUT44 列目をマイクロコントローラーのピンに接続し、ロー レベルに設定します。KEYIN1~KEYIN4その行をマイクロコントローラーの 4 つの IO ポートに接続し、ハイ レベルに設定します。押すと、C号按键最初の行が接続されます。 4列目を通過すると、1行目のハイレベルがローレベルに変わり、この時点でプレスが認識できますC号按键

3. 行と列のスキャン例

マトリックス キーボードの行と列のスキャン原理に従って、プログラムを使用してキーを識別し、対応する操作を実行します。

/*
程序名:行列扫描操作矩阵键盘   
编写人:bruce     
编写时间:2023年12月
硬件支持:STC12C2052AD系列  
接口说明:    
修改日志:  
  NO.1-								
*/

#include <STC12C2052AD.H> //STC12Cx052或STC12Cx052AD系列单片机头文件
// 定义LED灯
sbit LED = P3^7;
// 定义行扫描按键
sbit KEYIN1 = P1^0;
sbit KEYIN2 = P1^1;
sbit KEYIN3 = P1^2;
sbit KEYIN4 = P1^3;

//定义列扫描按键
sbit KEYOUT1 = P1^4;
sbit KEYOUT2 = P1^5;
sbit KEYOUT3 = P1^6;
sbit KEYOUT4 = P1^7;

/*
函数名:毫秒级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++);
	}
}


/*
作用:行列扫描方式识别矩阵键盘按键
参数:返回识别到的按键
返回:
*/
unsigned char keyScan(){
    
    
	unsigned char keyNum;
	/*
		扫描第一列行上面的按键
	*/
	KEYIN1,KEYIN2,KEYIN3,KEYIN4 = 1;
	KEYOUT2,KEYOUT3,KEYOUT4 = 1;
	// 第一列设置为低电平
	KEYOUT1 = 0;
	if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4 ){
    
    
		DELAY_MS(20);
		if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4){
    
    
			if(!KEYIN1){
    
    
				keyNum = 1;
			}
			if(!KEYIN2){
    
    
				keyNum = 2;
			}
			if(!KEYIN3){
    
    
				keyNum = 3;
			}
			if(!KEYIN4){
    
    
				keyNum = 4;
			}
		}
		//等待按键松开
		while(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4);
	}
	
	/*
		扫描第二列行上面的按键
	*/
	KEYIN1,KEYIN2,KEYIN3,KEYIN4 = 1;
	KEYOUT1,KEYOUT3,KEYOUT4 = 1;
	// 第二列设置为低电平
	KEYOUT2 = 0;
	if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4 ){
    
    
		DELAY_MS(20);
		if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4){
    
    
			if(!KEYIN1){
    
    
				keyNum = 5;
			}
			if(!KEYIN2){
    
    
				keyNum = 6;
			}
			if(!KEYIN3){
    
    
				keyNum = 7;
			}
			if(!KEYIN4){
    
    
				keyNum = 8;
			}
		}
		//等待按键松开
		while(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4);
	}
	
	/*
		扫描第三列行上面的按键
	*/
	KEYIN1,KEYIN2,KEYIN3,KEYIN4 = 1;
	KEYOUT1,KEYOUT2,KEYOUT4 = 1;
	// 第三列设置为低电平
	KEYOUT3 = 0;
	if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4 ){
    
    
		DELAY_MS(20);
		if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4){
    
    
			if(!KEYIN1){
    
    
				keyNum = 9;
			}
			if(!KEYIN2){
    
    
				keyNum = 10;
			}
			if(!KEYIN3){
    
    
				keyNum = 11;
			}
			if(!KEYIN4){
    
    
				keyNum = 12;
			}
		}
		//等待按键松开
		while(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4);
	}
	
	/*
		扫描第四列行上面的按键
	*/
	KEYIN1,KEYIN2,KEYIN3,KEYIN4 = 1;
	KEYOUT1,KEYOUT2,KEYOUT3 = 1;
	// 第四列设置为低电平
	KEYOUT4 = 0;
	if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4 ){
    
    
		DELAY_MS(20);
		if(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4){
    
    
			if(!KEYIN1){
    
    
				keyNum = 13;
			}
			if(!KEYIN2){
    
    
				keyNum = 14;
			}
			if(!KEYIN3){
    
    
				keyNum = 15;
			}
			if(!KEYIN4){
    
    
				keyNum = 16;
			}
		}
		//等待按键松开
		while(!KEYIN1 || !KEYIN2 || !KEYIN3 || !KEYIN4);
	}
	return keyNum;

}

void main(){
    
    
	while(1){
    
    
		switch(keyScan()){
    
    
			case 1:
				LED = 0;
				break;
			case 2:
				LED = 1;
				break;
			default:
				LED =1;
		}
	}

}

おすすめ

転載: blog.csdn.net/m0_38039437/article/details/135237797