理解矩阵键盘之前了解一下独立按键的触发原理(图)

STM32 4*4矩阵键盘实现原理(附程序)

:在了解矩阵键盘之前,有必要了解一下独立按键的触发原理。下图为常用独立按键接线图。

图片[1]-理解矩阵键盘之前了解一下独立按键的触发原理(图)-老王博客

:按键一端接地,另一端接单片机的GPIO。当按键没有按下时,这个路径实际上是开路,我们通常将单片机的引脚设置为输入上拉状态。所以当按钮未按下时,该引脚读取的电平始终为高电平。当按下按钮时,此时的引脚会被地面强行拉下。此时该引脚读取的电平为低电平,表示按键已被按下。独立按钮到这里就完成了,很简单。矩阵按键由多个独立按键组成,其触发原理与独立按键相同,但电路和程序扫描不同,稍微复杂一些。

  通常用的最多的矩阵键盘是4*4的。如下图:

图片[2]-理解矩阵键盘之前了解一下独立按键的触发原理(图)-老王博客

在编程中,扫描通常是逐行逐列进行,4*4矩阵键盘一共需要单片机的8个GPIO引脚,控制行的引脚设置为输出,并且控制列的管脚设置为输入上拉。

先扫描第一行,然后PD0~PD2输出高电平,PD3输出低电平4*4矩阵键盘判断程序,标记为0xF7。行确定后4*4矩阵键盘判断程序,开始扫描列,控制列的管脚为Input管脚,与0XF7相与,如果哪一位为0,则证明按下了哪一位。未按下按键时,IO口状态为**1111 0000,**扫描第一行输出PD3低电平,其他行输出高电平,即1111 0111,假设第一行按键按下,此时PD4管脚读低电平,此时读管脚发生变化

图片[3]-理解矩阵键盘之前了解一下独立按键的触发原理(图)-老王博客

程序如下:

key_board.c

#include "stm32f10x.h"
#include "delay.h"
#include "key_board.h"
//uint8_t Send_F=0;
void Keyboard_GPIO_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    
    KEYBOARD_GPIO_CLK_FUN(KEYBOARD_GPIO_CLK,ENABLE);
    
    //LINE    
    GPIO_InitStruct.GPIO_Pin=KEYBOARD_GPIO_PIN0|KEYBOARD_GPIO_PIN1|KEYBOARD_GPIO_PIN2|KEYBOARD_GPIO_PIN3;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_Init(KEYBOARD_GPIO_PORT,&GPIO_InitStruct);
    //ROW
    GPIO_InitStruct.GPIO_Pin=KEYBOARD_GPIO_PIN4|KEYBOARD_GPIO_PIN5|KEYBOARD_GPIO_PIN6|KEYBOARD_GPIO_PIN7;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_Init(KEYBOARD_GPIO_PORT,&GPIO_InitStruct);
}
uint16_t keyboard_scan(void)
{
    uint16_t key_val=0;
    uint16_t temp=0;
	
	
	/*************Scan  1st Line************************/
    GPIOD->ODR=0X00;
    GPIOD->ODR=0XF7;
    if((GPIOD->IDR&0XF0)!=0XF0)
    {
        delay_ms(50);
        if((GPIOD->IDR & 0XF0)!=0XF0)
        {
            temp=(GPIOD->IDR&0XF7);
            switch(temp)
            {
                case 0xE7:  key_val=1;   break;
                case 0xD7:  key_val=2;   break;
                case 0xB7:  key_val=3;   break;
                case 0x77:  key_val=4;   break;
                default:    key_val=0;   break;
            }
        }
    }
    
		/*************Scan  2st Line************************/
    GPIOD->ODR=0X00;
    GPIOD->ODR=0XFB;
    if((GPIOD->IDR&0XF0)!=0XF0)
    {
        delay_ms(50);
        if((GPIOD->IDR & 0XF0)!=0XF0)
        {
            temp=(GPIOD->IDR&0XFB);
            switch(temp)
            {
                case 0xEB:  key_val=5;  break;
                case 0xDB:  key_val=6;  break;
                case 0xBB:  key_val=7;  break;
                case 0x7B:  key_val=8;  break;
                default:    key_val=0;  break;
            }
        }
    }
		/*************Scan  3st Line************************/
    GPIOD->ODR=0X00;
    GPIOD->ODR=0XFD;
    if((GPIOD->IDR&0XF0)!=0XF0)
    {
        delay_ms(50);
        if((GPIOD->IDR & 0XF0)!=0XF0)
        {
            temp=(GPIOD->IDR&0XFD);
            switch(temp)
            {
                case 0xED:  key_val=9;   break;
                case 0xDD:  key_val=10;  break;
                case 0xBD:  key_val=11;  break;
                case 0x7D:  key_val=12;  break;
                default:    key_val=0;   break;
            }
        }
    }
		/*************Scan  4st Line************************/
    GPIOD->ODR=0X00;
    GPIOD->ODR=0XFE;
    if((GPIOD->IDR&0XF0)!=0XF0)
    {
        delay_ms(50);
        if((GPIOD->IDR & 0XF0)!=0XF0)
        {
            temp=(GPIOD->IDR&0XFE);
            switch(temp)
            {
                case 0xEE:  key_val=13;  break;
                case 0xDE:  key_val=14;  break;
                case 0xBE:  key_val=15;  break;
                case 0x7E:  key_val=16;  break;
                default:    key_val=0;   break;
            }
        }
    }
    return key_val;
}

key_board.h

#include "stm32f10x.h"
#ifndef     _KEY_BOARD_H_
#define     _KEY_BOARD_H_
#define   KEYBOARD_GPIO_PORT          GPIOD
#define   KEYBOARD_GPIO_CLK_FUN       RCC_APB2PeriphClockCmd
#define   KEYBOARD_GPIO_CLK           RCC_APB2Periph_GPIOD
//line    行
#define   KEYBOARD_GPIO_PIN0           GPIO_Pin_0
#define   KEYBOARD_GPIO_PIN1           GPIO_Pin_1
#define   KEYBOARD_GPIO_PIN2           GPIO_Pin_2
#define   KEYBOARD_GPIO_PIN3           GPIO_Pin_3
//row      列
#define   KEYBOARD_GPIO_PIN4           GPIO_Pin_4
#define   KEYBOARD_GPIO_PIN5           GPIO_Pin_5
#define   KEYBOARD_GPIO_PIN6           GPIO_Pin_6
#define   KEYBOARD_GPIO_PIN7           GPIO_Pin_7
//extern uint8_t Send_F;
extern void Keyboard_GPIO_Config(void);
extern uint16_t keyboard_scan(void);
#endif

程序结果如下:

图片[4]-理解矩阵键盘之前了解一下独立按键的触发原理(图)-老王博客

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论