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

STM32 4*4矩阵键盘实现原理(附程序)STM324*4矩阵键盘实现原理(附程序):理解矩阵键盘之前,先要了解一下独立按键的触发原理。下图是普通独立按键的接线图。:按键的一端接地,一端接MCU的GPIO。当按键没有被按下的时候,这条路其实是一个断路,我们通常会将单片机该引脚设置成输入上拉状态。所以当按键没有按下的时候,这个引脚读到的电平一直是高电平。当按下按键的时候,那么此时的引脚会被地强行拉低,此时这个引脚读到的电平为低电平,那说明按键已经被按下。独立按键到这里已经说完了,很简单。矩阵按键是由多个独立按键组成的

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

: 理解矩阵键盘之前,先要了解一下独立按键的触发原理。下图是普通独立 按键的接线图。
在这里插入图片描述

: 按键的一端接地,一端接MCU的GPIO。当按键没有被按下的时候,这条路其实是一个断路,我们通常会将单片机该引脚设置成输入上拉状态。所以当按键没有按下的时候,这个引脚读到的电平一直是高电平。当按下按键的时候,那么此时的引脚会被地强行拉低,此时这个引脚读到的电平为低电平,那说明按键已经被按下。独立按键到这里已经说完了,很简单。矩阵按键是由多个独立按键组成的,所以它的触发原理和独立按键相同,只是在电路和程序扫描上不同,略微复杂一点。

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

在这里插入图片描述
程序设计上通常采用逐行逐列进行扫描,4*4的矩阵键盘一共需要8个单片机的GPIO引脚,将控制行的引脚设置成输出,控制列的引脚设置成输入上拉。

先扫描第一行,那么就将PD0~PD2输出高电平,将PD3输出低电平,记为0xF7,行确定好后,开始扫描列,控制列的引脚为输入引脚,将其和0XF7相与,如果哪一位为0,那么就证明哪一个被按下。按键没有被按下的时候,IO口的状态为 **1111 0000 ,**扫描第一行将PD3输出低电平,其他行输出高电平,即为1111 0111,假设第一个按键被按下,那么此时PD4引脚读到低电平,那么读到的引脚变化

GPIOD->IDR & 1111 0111=1110 0111//这样就证明了第一个按键被按下。以此类推。

程序如下:

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

程序运行结果如下:

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38805.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注