STM32 3*3矩阵按键(寄存器版本)

本文介绍了一种使用行列扫描法在STM32微控制器上实现矩阵键盘的检测方法。通过配置PA2-7引脚,分别设置为输入上拉和输出低电平,利用电平变化检测按键状态,最终确定按键位置并返回相应值。在主函数中,根据检测结果打印按键值,实现了实时的按键输入显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我使用的引脚为:PA2-7

电路图片:(仅供电路图参考)

思路:(行列扫描法),起始可以将2,3,4设置为上拉输入(下拉输入),5,6,7设置为输出低电平(输出高点平)当按键按下的时候,电平会由1->0,这样就可以检测到电平的变化,从而获得对应的按键接口值

首先,使能你对应的时钟,然后需要把你需要的引脚置零

RCC->APB2ENR|=1<<2;	
GPIOA->CRL&=0XFF;		//	清零
端口配置低寄存器将其配置为输入上拉的模式,即(1000)
GPIOA->CRL|=0X33388800;

注意的是你设置为1000的时候,你不能确定是上拉还是下拉,所以你需要进行ODR操作

GPIOA->ODR|=1<<2;			//上拉
GPIOA->ODR|=1<<3;
GPIOA->ODR|=1<<4;

当你需要下拉的时候将1换成0即可,并左移至向相应的引脚

然后将5,6,7设置为低电平输出

    PAout(5) = 0;
	PAout(6) = 0;				//设置为低电平
	PAout(7) = 0;

然后进行检测,当2,3,4其中任何一个检测到低电平的时候,进行相应的返回值(若是二,则知证明是在第一行,三则是在第二行.....)

if(PAin(2) == 0||PAin(3) == 0||PAin(4) == 0)
	{
		delay_ms(10);
		if(PAin(2) == 0)
		{
			i = 1;
		}
		if(PAin(3) == 0)
		{
			i = 2;
		}
		if(PAin(4) == 0)
		{
			i = 3;
		}
	}

这样就得知了按键是在哪一行,然后接下里就是寻找是在哪一列,将输入和输出进行反转

GPIOA->CRL&=0X000000FF;		//	清零//将pa2,3,4设置为输出,5,6,7设置为输入
	GPIOA->CRL|=0X88833300;
	GPIOA->ODR|=1<<5;			//上拉
	GPIOA->ODR|=1<<6;
	GPIOA->ODR|=1<<7;
	PAout(2) = 0;
	PAout(3) = 0;				//设置为低电平
	PAout(4) = 0;
	if(PAin(5) == 0||PAin(6) == 0||PAin(7) == 0)
	{
		delay_ms(10);
		if(PAin(5) == 0)
		{
			j = 1;
		}
		if(PAin(6) == 0)
		{
			j = 2;
		}
		if(PAin(7) == 0)
		{
			j = 3;
		}
	}

最后在借助i和j判断是在哪个位置

if(i == 1)
	{
		if(j == 1)
		{	
			return 1;
		}
		if(j == 2)
		{	
			return 2;
		}
		if(j == 3)
		{	
			return 3;
		}
	}
	if(i == 2)
	{
		if(j == 1)
		{	
			return 4;
		}
		if(j == 2)
		{	
			return 5;
		}
		if(j == 3)
		{	
			return 6;
		}
	}
	if(i == 3)
	{
		if(j == 1)
		{	
			return 7;
		}
		if(j == 2)
		{	
			return 8;
		}
		if(j == 3)
		{	
			return 9;
		}
	}
	if(i==0&&j==0)
		return 0;

在主函数中进行接受相应的字符,然后在串口打印相应的值

u8 t;	  
	Stm32_Clock_Init(9); 	//系统时钟设置
	delay_init(72);	     	//延时初始化 
	uart_init(72,9600);	 //串口初始化为9600
	while(1)
	{
		t = KEY_Init();
		switch(t)
		{
			case '1':
					delay_ms(1000);
					printf("1\r\n");
					break;
			case '2':
					delay_ms(1000);
					printf("2\r\n");
					break;
			case '3':
					delay_ms(1000);
					printf("3\r\n");
					break;
			case '4':
					delay_ms(1000);
					printf("4\r\n");
					break;
			case '5':
					delay_ms(1000);
					printf("5\r\n");
					break;
			case '6':
					delay_ms(1000);
					printf("6\r\n");
					break;
			case '7':
					delay_ms(1000);
					printf("7\r\n");
					break;
			case '8':
					delay_ms(1000);
					printf("8\r\n");
					break;
			case '9':
					delay_ms(1000);
					printf("9\r\n");
					break;
			case '0':
					delay_ms(1000);
					printf("没有按键输入\r\n");
					break;
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cyrus_Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值