使用STM32CubeMX配置矩阵键盘

矩阵键盘的选择


我这里使用的是某宝一块四包邮的4*4矩阵键盘,感觉对大部分简单工程的实现绰绰有余

Cubemx工程的配置

新建工程,配置RCC,SYS,时钟树等基础功能

一般设置为最大速率,之后点击OK可以实现一键配置,时钟源这里选择的是高速外部时钟源(HSE)

引脚配置

随便找几个引脚
根据自己单片机的引脚数量和操作的方便性配置矩阵键盘的引脚
一般为四个输入,四个输出,输入模式设为上拉输入

代码生成


设置工程名、文件路径(切记不要出现中文路径,笔者帮你们试过了,代码会被吞);IDE选择MDK-ARM,此时系统会在keil中生成代码


点击生成代码,打开工程

Keil的配置

在main.c文件中加入矩阵键盘扫描函数如下,引脚根据自己的配置更换

/* USER CODE BEGIN 4 */
uint8_t Key_Scan(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	/*前4个端口输出低电平*/
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);
	
	//前4个端口推挽输出
	GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	
	//后4个端口上拉输入
	GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	HAL_Delay(10);
	if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_4)==GPIO_PIN_RESET)//读取第1行
	{
		/*后4个端口输出低电平*/
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
		//后4个端口推挽输出
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		//前4个端口上拉输入
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull = GPIO_PULLUP;
		GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0)==GPIO_PIN_RESET)return 4;
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_1)==GPIO_PIN_RESET)return 3;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_2)==GPIO_PIN_RESET)return 2;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_3)==GPIO_PIN_RESET)return 1;
	}
	if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_5)==GPIO_PIN_RESET)//读取第2行
	{
		/*后4个端口输出低电平*/
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
		//后4个端口推挽输出
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		//前4个端口上拉输入
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull = GPIO_PULLUP;
		GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0)==GPIO_PIN_RESET)return 8;
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_1)==GPIO_PIN_RESET)return 7;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_2)==GPIO_PIN_RESET)return 6;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_3)==GPIO_PIN_RESET)return 5;
	}	
	if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_6)==GPIO_PIN_RESET)//读取第3行
	{
		/*后4个端口输出低电平*/
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
		//后4个端口推挽输出
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		//前4个端口上拉输入
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull = GPIO_PULLUP;
		GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0)==GPIO_PIN_RESET)return 12;
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_1)==GPIO_PIN_RESET)return 11;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_2)==GPIO_PIN_RESET)return 10;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_3)==GPIO_PIN_RESET)return 9;
	}
	if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_12)==GPIO_PIN_RESET)//读取第4行
	{
		/*后4个端口输出低电平*/
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
		//后4个端口推挽输出
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		//前4个端口上拉输入
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull = GPIO_PULLUP;
		GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0)==GPIO_PIN_RESET)return 16;
		if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_1)==GPIO_PIN_RESET)return 15;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_2)==GPIO_PIN_RESET)return 14;
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_3)==GPIO_PIN_RESET)return 13;
	}
	return 0;
}
/* USER CODE END 4 */

加入函数声明,使扫描函数能正常调用

/* USER CODE BEGIN PFP */
uint8_t Key_Scan(void);
/* USER CODE END PFP */

以下是笔者在学习中书写的一段代码,未完全展示,将其作为笔者自己的测试程序,仅作参考,读者可以通过串口验证按键输入是否有效,在此不再赘述

/* USER CODE BEGIN 3 */
		int i;
		i = Key_Scan();
		if(i == 1)
		{
	  HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
			for(j=0;j<100;j++)
			{
			temp[j]=n*Sine12bit[j]/30;
			}
		HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,(uint32_t*)temp,100,DAC_ALIGN_12B_R);//开启正弦波输出
		HAL_Delay (500);
		}
		if(i == 2)
		{
		HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
for(j=0;j<100;j++)
			{
			temp[j]=n*sanjiao[j]/30;
			}			
		HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,(uint32_t*)temp,100,DAC_ALIGN_12B_R);//开启三角波输出
		HAL_Delay (500);
		}
		if(i == 3)
		{
		HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
for(j=0;j<100;j++)
			{
			temp[j]=n*fangbo[j]/30;
			}			
		HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,(uint32_t*)temp,100,DAC_ALIGN_12B_R);//开启方波输出
		HAL_Delay (500);
		}
		if(i == 5)
		{
		TIM2->ARR *=2;
		HAL_Delay(500);
		}
		if(i == 6)
		{
		TIM2->ARR /=2;
		HAL_Delay(500);
		}
		if(i == 9)
		{
		n -=1;
			HAL_Delay(500);
		}			
		if(i ==10)
		{
		  n+=1;
			HAL_Delay(500);
		}
		
		HAL_Delay(10);
  }
  /* USER CODE END 3 */

值得注意的是,笔者在每次的按键切换中都加入了延时函数,这个操作是为了方式单片机将我们的按键行为误认为意外抖动而设计,即消抖,可以提高按键操作的稳定性。

引脚连接

结果展示


一段正弦波显示了出来,可以看到,效果灰常好啊!感兴趣的读者可以自己设计一段DAC程序,非常有趣。

至此,4*4矩阵键盘配置完成。

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32CubeMX配置矩阵键盘

发表评论