stm32中4*4矩阵按键使用

文章讲述了如何在STM32F103中使用矩阵键盘,处理GPIO引脚重映射问题,避免与其他模块冲突,并提供了一段包含键值初始化、扫描和应用层函数的代码实例。
摘要由CSDN通过智能技术生成

 楼主使用的是下面这种矩阵键盘,由于网上大多资源都是同一GPIO配置的,如果我们使用了其他模块例如蓝牙模块,OLED等等,会占用同一GPIO口引脚,导致无法照搬网上。而且网上一些代码质量比较差,垃圾,难懂。以下具体原理不介绍,大家应该也在别的博客了解过,直接看代码。

下面这是我引脚配置代码:

在stm32F103上PA15 PB3 PB4等等一些引脚需要我们重映射。

void Key_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
	GPIO_PinRemapConfig( GPIO_Remap_SWJ_Disable,ENABLE);
	// 列
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	// 行
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; 
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_15 ;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	for(int i= 0;i < ROWS;i++)
	{
			GPIO_SetBits(gpio_Key[i].GPIO_X, gpio_Key[i].GPIO_PIN_X);   //行置高电平
	}
}	

 按键应用层定义:

#define  ROWS   4
#define  COLS   4

uint8_t keyboard_value[ROWS][COLS] = {
	{0x01, 0x02, 0x03, 0x0C},
	{0x04, 0x05, 0x06, 0x0D},
	{0x07, 0x08, 0x09, 0x0E},
	{0x0A, 0x00, 0x0B, 0x0F},
};


struct GPIO_Key gpio_Key[ROWS+COLS] = 
{
		{GPIOA,GPIO_Pin_15},  // row
		{GPIOB,GPIO_Pin_3},
		{GPIOB,GPIO_Pin_4},
		{GPIOB,GPIO_Pin_5},
		{GPIOB,GPIO_Pin_6},		// col
		{GPIOB,GPIO_Pin_7},
		{GPIOB,GPIO_Pin_8},
		{GPIOB,GPIO_Pin_9},
};

按键读取函数:

uint8_t Key_Scan(u8 i)
{
    uint8_t j;
    GPIO_ResetBits(gpio_Key[i].GPIO_X, gpio_Key[i].GPIO_PIN_X); 
		for (j = 0; j < COLS; j++)
		{
				if(!GPIO_ReadInputDataBit(gpio_Key[ROWS+j].GPIO_X, gpio_Key[ROWS+j].GPIO_PIN_X))				// 按下
				{
							delay_ms(10);
							if(!GPIO_ReadInputDataBit(gpio_Key[ROWS+j].GPIO_X, gpio_Key[ROWS+j].GPIO_PIN_X))  // 按下
							{ 		
										GPIO_SetBits(gpio_Key[i].GPIO_X, gpio_Key[i].GPIO_PIN_X);
										return keyboard_value[i][j];
							}
				}
		}
		GPIO_SetBits(gpio_Key[i].GPIO_X, gpio_Key[i].GPIO_PIN_X);
		return 0xFF; 
}

使用案例:(可以实现松手触发按下)

//  按键第一行
void key0_Task(void)
{
    	    u8 row0_val = 0;
			static u8 key0_flag = false;
			row0_val = Key_Scan(0);
			if(row0_val != 0xFF && key0_flag == false)
			{
					key0_flag = true;
					printf("%d\n\r",row0_val);
					key_val = row0_val;
			}else if(row0_val == 0xFF)
			{
					key0_flag = false;
			}
}
//  按键第二行
void key1_Task(void)
{
			u8 row1_val = 0;
			static u8 key1_flag = false;
			row1_val = Key_Scan(1);
			if(row1_val != 0xFF && key1_flag == false)
			{
					key1_flag = true;
					printf("%d\n\r",row1_val);
					key_val = row1_val;
			}else if(row1_val == 0xFF)
			{
					key1_flag = false;
			}
}

效果展示:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值