STM32 NUCLEO-F410RB 学习笔记(三)4x4矩阵键盘的使用

本文介绍了一种在不使用中断机制的情况下实现键盘检测和呼吸灯控制的方法。通过检测按键按下并消除按键抖动,确保了主程序执行不受干扰。同时,通过引入bool型变量press避免重复读取键盘,保持了MPU处理速度,实现了良好的呼吸灯闪烁频率。
该文章已生成可运行项目,

实现思路
开始时四列均输出高电平,键盘处于检测状态。检测到按键按下(读IO口值不为0)转去执行读取输入字符子程序。
为避免按键抖动引起干扰,引入按键消抖。如果按键确实按下,读IO口的值不为0,对读取的IO口值进行译码。如果同时按下多个同一列按键,键盘不确定按下的是什么键,返回’?’,否则返回输入的字符。由于一次按下时间较长(相对处理器执行速度),避免重复读键盘导致干扰呼吸灯主程序执行,需要在主程序中引入一个bool型变量press,平时不按下按键时置false ,检测到按下并且不是误触发则读取字符后置true,误触发仍置false,并且整个检测块被if块保护,在同一次按键主程序又执行到检测按键处时不会重复扫描和分析按键,避免降低MPU处理速度从而影响呼吸灯闪烁频率。最终调试发现效果很好。虽然没有使用中断机制,但是键盘检测模块的执行效果就像是使用中断机制一样,对主程序的执行没有任何影响。
键盘按键映射图

C1C2C3C4
R1123A
R2456B
R3789C
R4*0#D

硬件接线

R1--------PC0
R2--------PC1
R3--------PC2
R4--------PC3
C1--------PA0
C2--------PA1
C3--------PA4
C4--------PB0
PA5-------PA8

源代码

#include "mbed.h"

#define IOS (0x0F) // PC_0+PC_1+PC_2+PC_3
//R1-R4: PC0-PC3, C1:PA0, C2:PA1, C3:PA4, C4:PB0

PortIn myIOs(PortC, IOS);
 
DigitalOut led(LED1);
DigitalOut C1(PA_0);
DigitalOut C2(PA_1);
DigitalOut C3(PA_4);
DigitalOut C4(PB_0);
PwmOut pwm(PA_8);
 
char keyboardInputHandler();
 
int main() {
	myIOs.mode(PullDown);
	float i = 0.5;		//dc
	bool flag = true;
	bool press = false;
	pwm.period_ms(10);
  	char input;
	
	while(1)
	{
		led.write(PA_8);
		C1=1,C2=1,C3=1,C4=1;
		if(myIOs.read()!=0) 
		{/*键盘扫描程序*/
			if(!press)
			{
				input = keyboardInputHandler();
				if(input != '\0')
				{
					printf("Input content is character %c.\r\n",input);
					press=true;
				}
				else press=false;
			}
		}
		else press=false;
		pwm.write(i);
		if(flag)
		{
			i+=0.01;
			if(i>=1.0) flag=false;
		}
		else {
			i-=0.01;
			if(i<=0) flag=true;
		}
		wait_ms(10);
	}
}
char keyboardInputHandler()
{
	int i;
	char a;
    
	C1=1,C2=1,C3=1,C4=1;
	if(myIOs.read()==0) return '\0';
	for(i=1;i<5;i++)
	{
		if(i==1) {
			C1=1,C2=0,C3=0,C4=0;
			if(myIOs.read()!=0)
			{
				wait_ms(20);
				if(myIOs.read()!=0)
				{
					if(myIOs.read()==0b0001)
						a='1';
					else if(myIOs.read()==0b0010)
						a='4';
					else if(myIOs.read()==0b0100)
						a='7';
					else if(myIOs.read()==0b1000)
						a='*';
					else a='?';
					break;
				}
				else a='\0';
			}
			else a='\0';
		}
		else if(i==2) {
		C1=0,C2=1,C3=0,C4=0;
			if(myIOs.read()!=0)
			{
				wait_ms(20);
				if(myIOs.read()!=0)
				{
					if(myIOs.read()==0b0001)
						a='2';
					else if(myIOs.read()==0b0010)
						a='5';
					else if(myIOs.read()==0b0100)
						a='8';
					else if(myIOs.read()==0b1000)
						a='0';
					else a='?';
					break;
				}
				else a='\0';
			}
			else a='\0';
		}
		else if(i==3) {
			C1=0,C2=0,C3=1,C4=0;
			if(myIOs.read()!=0)
			{
				wait_ms(20);
				if(myIOs.read()!=0)
				{
					if(myIOs.read()==0b0001)
						a='3';
					else if(myIOs.read()==0b0010)
						a='6';
					else if(myIOs.read()==0b0100)
						a='9';
					else if(myIOs.read()==0b1000)
						a='#';
					else a='?';
					break;
				}
				else a='\0';
			}
			else a='\0';
		}
		else {
			C1=0,C2=0,C3=0,C4=1;
			if(myIOs.read()!=0)
			{
				wait_ms(20);
				if(myIOs.read()!=0)
				{
					if(myIOs.read()==0b0001)
						a='A';
					else if(myIOs.read()==0b0010)
						a='B';
					else if(myIOs.read()==0b0100)
						a='C';
					else if(myIOs.read()==0b1000)
						a='D';
					else a='?';
					break;
				}
				else a='\0';
			}
			else a='\0';
		}	
	}
			
	return a;
}
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值