STM32项目实例:矩阵键盘扫描

文摘   2024-09-16 07:03   山东  

开发板配备了独立按键与矩阵键盘切换电路,上一节我们实现了独立按键输入控制,本节我们将和大家一起实现矩阵键盘扫描。

1 矩阵键盘电路

如图1所示,为了便于多键值输入,同时节约MCUI/O口资源,开发板设计了独立按键/矩阵键盘切换电路,将图中跳线开关P812引脚短接,电路表现为矩阵键盘,由34列共12个按键组成,行信号由MCUPE4~PE6引脚控制,列信号由MCUPE0~PE3控制。

1 矩阵键盘电路连接

2 矩阵键盘扫描原理

矩阵键盘确定键值扫描方法主要有行扫描、列扫描和行列扫描,行列扫描分两步确定按键的行号和列号,需要不断切换端口管脚工作模式,不太适合本项目。行扫描和列扫描本质上是一样的,均为依次将某一行(列)输出低电平,读取所有列(行)的管脚电平,确定行列编号,相对来说,行扫描更接近大众思维习惯,所以本项目采用行扫描方法确定矩阵键盘键值。

下面以图1所示连接关系为例讲解其工作原理,扫描前需要设置行线为推挽输出模式列线为上拉输入模式。依次控制行线PE4~PE6输出低电平,读取列线PE0~PE3电平状态,如果其中包含低电平,则可由其对应的行列信号确定按键编号。例如当行线PE5输出低电平,读出列线PE1为低电平时,则可以确定第二行第二列按键K6被按下。在进行矩阵键盘扫描时同样也需要进行消抖处理。

3 矩阵键盘实例

本节设计一简单项目验证矩阵键盘行扫描方法,对34矩阵键盘进行扫描,并将键值以8421BCD码(每4位二进制数表示一位十进制数)形式显示于LED指示灯。项目具体实施步骤为:

1步:复制第3章创建的工程模板文件夹到桌面,并将文件夹重命名为0602 MatrixKey

2步:打开工程模板文件夹里面的Template.ioc文件,启动CubeMX配置软件,首先在引脚视图下面将PE0~PE3设置为GPIO_Input模式,PE4~PE6PF0~PF7设置为GPIO_Output模式。然后选择System Core类别下的GPIO子项,将按键输入引脚PE0~PE3设置为上拉输入工作模式,将按键行扫描信号引脚PE4~PE6LED指示灯控制引脚PF0~PF7均设置为推挽、低速、无上拉/下拉、初始输出高电平。单击GENERATE CODE按钮生成初始化工程。

3步:打开MDK-RAM文件夹下面的工程文件Template.uvprojx,将生成工程编译一下,没有错误和警告,则开始用户程序编写。GPIO初始化程序存放在CubeMX创建的gipo.c文件中,部分代码如下

void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* GPIO Ports Clock Enable */           __HAL_RCC_GPIOE_CLK_ENABLE();

__HAL_RCC_GPIOC_CLK_ENABLE();  __HAL_RCC_GPIOF_CLK_ENABLE();

__HAL_RCC_GPIOH_CLK_ENABLE();  __HAL_RCC_GPIOA_CLK_ENABLE();

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6,PIO_PIN_SET);

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3

|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_SET);

/*Configure GPIO pins : PE2 PE3 PE0 PE1 */

GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_1;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/*Configure GPIO pins : PE4 PE5 PE6 */

GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/*Configure GPIO pins : PF0 PF1 PF2 PF3 PF4 PF5 PF6 PF7 */

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3

|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

}

上述代码和CubeMX配置选项是一一对应的,且用户无须任何修改。

4步:打开main.c文件,在程序沙箱1内定义程序中需要用到的变量和数组,在while程序沙箱内编写行扫描程序,参考程序如下所示:

int main(void)

{

/* USER CODE BEGIN 1 */

  uint16_t i,KeyVal=0;

uint8_t PreLine[3]={2,0,1};                //前一行的行号

/* USER CODE END 1 */

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

/* USER CODE BEGIN WHILE */

while (1)

{

for(i=0;i<3;i++)

{

if((GPIOE->IDR&0x0F)!=0x0F)       //有键按下

{

HAL_Delay(16);                //延时消抖

if((GPIOE->IDR&0x0F)!=0x0F)   //仍然按下

{

switch((GPIOE->IDR&0x0F))

{

case 0x0E:KeyVal=4*PreLine[i]+1;break;  //1

case 0x0D:KeyVal=4*PreLine[i]+2;break;  //2

case 0x0B:KeyVal=4*PreLine[i]+3;break;  //3

case 0x07:KeyVal=4*PreLine[i]+4;break;  //4

default  :break;

}

}

}

GPIOE->ODR=~(1<<(i+4));    //输出行控制信号

}

GPIOF->ODR=~((KeyVal/10<<4)+KeyVal%10);  //键值输出

/* USER CODE END WHILE */

}

}

上述程序完成了矩阵按键的扫描、消抖、动作分离的全部内容,代码紧凑高效,为帮助大家读懂程序,掌握矩阵按键的原理和应用方法,现对其中重要的两部分内容加以说明。

首先,读者可能发现,程序的编写思路并不符合上节所介绍的行扫描原理,主要表现为输出行信号和读取列管脚的顺序上。如果完全按照行扫描原理编写程序是识别不到任何按键的,这是因为任何信号从输出到稳定都需要一定时间,有时它足够快而有时却不够快,这取决于具体的电路设计,本例中列信号没来得及变为低电平,行扫描就已转入下一行。虽然可以通过适当的编程方法加以解决,但是会使得程序趋向复杂,响应时间显著增加。

因为矩阵键盘是循环扫描,所以我们可以先识别上一次行输出信号对应的按键信息,消抖、处理完成之后再输出本行的控制信息。这里输入输出的顺序颠倒是为了让输出信号有足够的时间来稳定,并有足够的时间来完成它对输入的影响,当按键电路中还有硬件电容消抖时,这样处理就是绝对必要的了,虽然这样使得程序理解起来有点绕,但其适应性是最好的,换个说法就是,这段程序足够“健壮”,足以应对各种恶劣情况。

其次,程序多采用直接操作寄存器完成对行列输入输出控制,列管脚电平状态读取是通过GPIOE->IDR&0x0F语句完成的,即取GPIOE输入数据寄存器的低4位,对应PE0~PE3引脚电平状态。行控制信号输出是通过GPIOE->ODR=~(1<<(i+4))语句实现的,其中i代表行号,范围0~2,所以行号加上4,使得移位输出管脚对应PE4~PE6,又由于输出低电平表示扫描该行,所以移位后数值还需要取反。键值BCD码输出的实现方法是先将键值十位、个位拆开,然后十位左移4位加上个位,再将其取反,送给GPIOF端口,即可通过LED亮灭表示按键编号。

第五步:编译工程,直到没有错误为止,下载程序到开发板,复位运行,检查实验效果。

4 使用教材
教程可复制文件下载
STM32项目实例:矩阵键盘扫描.docx

人工智能科学与技术
分享教学成果 | 传播前沿科技| 推荐优秀图书
 最新文章