【STM32】4*4矩阵键盘扫描程序(扫描方式)

由于买的最小系统开发板只有一个按键感觉不大方便调试和搞其他东东,所以又在某宝买了一个4*4矩阵键盘拓展一下按键哈。能力有限,参照之前学的51单片机例程写了份简单粗暴型的按键扫描程序,如需在大项目中使用还是得用中断来处理比较好~
点击下载源码

矩阵键盘实物和原理图


图中厂家给的图应该标错了序号,从左到右是S1-S4、S5-S8、S9-S12、S13-S16为一行,小伙伴们自行理会啦。

总体思路:先向矩阵的4行输出低电平,然后检测4列的输入,若为’0’的那列即该列有按键按下;接着向列输出高电平,检测行输入,若为’1’的那行即为按键在该列的位置,从而确定按键所在的某列某行了。(先检测行再检测列也是可以的)

void KEY1_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOA、B
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入  
   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11;  
   GPIO_Init(GPIOB,&GPIO_InitStructure); 
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //推挽输出
   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;      
   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
   GPIO_Init(GPIOA,&GPIO_InitStructure);       
   GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //行输出低电平,扫描列
}
void KEY2_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

	
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //推挽输出
   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_10;
   GPIO_Init(GPIOB,&GPIO_InitStructure);
   GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11);  //扫描行
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;   //下拉输入
   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
   GPIO_Init(GPIOA,&GPIO_InitStructure);	 
}
u8 KeyScan(void)
{
	u8 column=0,KeyValue=0;
    KEY1_Init();    //行输入低电平,扫描列
	while(1)
	{
		if(PBin(0)==0)
		{
			delay_ms(50);
			if(PBin(0)==0)
			{
				column=1;        //第一列
			}
		}
		if(PBin(1)==0)
		{
			delay_ms(50);
			if(PBin(1)==0)
			{
				column=2;        //第二列
			}
		}
		if(PBin(10)==0)
		{
			delay_ms(50);
			if(PBin(10)==0)
			{
				column=3;        //第三列
			}
		}
		if(PBin(11)==0)
		{
			delay_ms(50);
			if(PBin(11)==0)
			{
				column=4;        //第四列
			}
		}		
		if(column==1)  
		{
				KEY2_Init();     //列输出高电平,扫描行		           
					if(PAin(7)==1) //第一列第一行
					{
						KeyValue=1;
						break;   
					}
					if(PAin(6)==1) //第一列第二行
					{
						KeyValue=5;
						break;   
					}
					if(PAin(5)==1) //第一列第三行
					{
						KeyValue=9;
						break;   
					}
					if(PAin(4)==1) //第一列第四行
					{
						KeyValue=13;
						break;   
					}
				
		}	
		
		if(column==2)
		{
				KEY2_Init();     //以下同理				           
					if(PAin(7)==1)
					{
						KeyValue=2;
						break;   
					}
					if(PAin(6)==1)
					{
						KeyValue=6;
						break;  
					}
					if(PAin(5)==1)
					{
						KeyValue=10;
						break; 
					}
					if(PAin(4)==1)
					{
						KeyValue=14;
						break;  
					}
				
		}		
		if(column==3)
		{
				KEY2_Init();    			           
					if(PAin(7)==1)
					{
						KeyValue=3;
						break;   
					}
					if(PAin(6)==1)
					{
						KeyValue=7;
						break;   
					}
					if(PAin(5)==1)
					{
						KeyValue=11;
						break;   
					}
					if(PAin(4)==1)
					{
						KeyValue=15;
						break;   
					}
				
		}
		
		if(column==4)
		{
				KEY2_Init();             
					if(PAin(7)==1)
					{
						KeyValue=4;
						break;  
					}
					if(PAin(6)==1)
					{
						KeyValue=8;
						break;   
					}
					if(PAin(5)==1)
					{
						KeyValue=12;
						break;   
					}
					if(PAin(4)==1)
					{
						KeyValue=16;
						break;   
					}				
		}
		
	}
   return KeyValue;
}

效果图

注意事项:
①在选择开发板的IO口时一定要看看原理图或者数据手册,确定这8个IO口是可用的(小编在使用时本来用了PB2引脚的,结果调试了好久都没得到正确的结果,检查了N多遍程序觉得没问题,最后回归到硬件上才发现原来只有PB2与BOOT1和GND相连了,所以就导致大部分结果都出错啦,希望其他小伙伴别走进坑哈哈)
②关于IO口输入输出模式的选择问题。输出模式一般都是选择推挽输出的,因为可直接输出0或1;关于输入模式的话,按键一边输出了0(1),那么要检测是否有按键按下,另一边的应选择上拉输入设置该引脚为1(下拉输入设置该引脚为0)。
③该程序没有写按键松开检测程序,所以不松开按键的话可以一直检测到;想弄按键松开检测的小伙伴可以设置一个静态变量作为按键松开的标志即可。

这里用的方法比较简单易懂,但是比较占用MCU的资源。若大家有很好的推荐,欢迎交流沟通呀!!!若大家要下载源码可以留言邮箱(设置了0C币发现过几天会自动升价)。

  • 37
    点赞
  • 251
    收藏
    觉得还不错? 一键收藏
  • 74
    评论
我可以为您提供一个简单的STM32 4 * 4矩阵键盘扫描程序的示例代码。请注意,此代码并未进行实际测试,也可能需要进行一些自定义修改以适应您的特定硬件设置。 #include "stm32f10x.h" int main(void) { /* Enable GPIOC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); /* Configure PC0-PC3 as outputs (rows) */ GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStruct); /* Configure PC4-PC7 as inputs (columns) */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOC, &GPIO_InitStruct); /* Initialize variables */ uint16_t keys[4][4] = {{1, 2, 3, 10}, {4, 5, 6, 11}, {7, 8, 9, 12}, {14, 0, 15, 13}}; uint8_t row_pins[4] = {GPIO_Pin_0, GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_3}; uint8_t col_pins[4] = {GPIO_Pin_4, GPIO_Pin_5, GPIO_Pin_6, GPIO_Pin_7}; uint8_t row, col; /* Main loop */ while (1) { /* Scan each row */ for (row = 0; row < 4; row++) { /* Set row pin high */ GPIO_SetBits(GPIOC, row_pins[row]); /* Check each column */ for (col = 0; col < 4; col++) { /* If column pin is low, key is pressed */ if (GPIO_ReadInputDataBit(GPIOC, col_pins[col]) == Bit_RESET) { uint16_t key = keys[row][col]; /* TODO: handle key press */ } } /* Set row pin low */ GPIO_ResetBits(GPIOC, row_pins[row]); } } } 希望这段代码能对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 74
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值