淘客手机版网站怎么做wordpress 显示字体
矩阵键盘

丹山起凤 2019-05-27 11:05:19 
 3785 
 收藏 8
分类专栏: 单片机
矩阵键盘的原理及应用 - MARS的博客 - CSDN博客 https://blog.csdn.net/qq_40642465/article/details/80334530
矩阵键盘原理图:

第一行的行控制线接到p17,第二行的行控制线接到p16,第三行的行控制线接到p15,第4行的行控制线接到p14
 第一列的列控制线接到p13,第二列的列控制线接到p12,第三列的列控制线接到p11,第四列的列控制线接到p10
 矩阵键盘的原理和独立按键类似,另外我们可以把矩阵键盘的任意一行或一列作为一个独立键盘使用,假如我们把第一行作为独立键盘,那么我们只需要让P17输出高电平,其余7个io口输出低电平即可,假如我们按下了s1,那么p13的电平就会被拉低,变为低电平,所以我们可以通过查找低4位里哪一位为低电平就可以知道哪个按键按下了。
 下面来说说矩阵按键扫描原理(即当我们按下一个矩阵键盘的按键时,如何获取按键的位置)
 方法有2种,一种是逐行扫描,一种是行列扫描.接下来就主要讲讲行列扫描.
1、行列扫描法
 行列扫描的话,就是一开始让p1口高4位输出高电平,低4位输出低电平,若这4行按键里,有按键按下了,那么那一行按键对应的io的电平就会被拉低,我们就可以知道按键的行坐标.获取按键列坐标的方法也是类似的,就是一开始让p1口高4位输出低电平,低4位输出高电平,若这4列按键里,有按键按下了,那么那一列按键对应的io的电平就会被拉低,我们就可以知道按键的列坐标,获得了行坐标x,列坐标y后,4*(x-1)+y就是按键的编号.
 接下来贴份应用的代码,目的就是赋予16个按键键值,分别对应的键值是从0~F。按下一个键,第一个数码管就显示对应的键值
- #include<reg52.h>
 - sbit lsa=P2^2;
 - sbit lsb=P2^3;
 - sbit lsc=P2^4;
 - #define duanxuan P0
 - #define keyboard P1
 - int zxm[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
 - int x,y;
 - void delay(int i)
 - {
 - while(i--);
 - }
 - void keyproc()
 - {
 - int a=0;
 - P1=0x0f;//检测是哪一列有按键按下;
 - if(P1!=0x0f)
 - {
 - delay(1000);
 - if(P1!=0x0f)
 - {
 - P1=0x0f;
 - switch(P1)
 - {
 - case(0x07):y=1;break;
 - case(0x0b):y=2;break;
 - case(0x0d):y=3;break;
 - case(0x0e):y=4;break;
 - }
 - }
 - P1=0xf0;//检测是哪一行有按键按下
 - switch(P1)
 - {
 - case(0x70):x=1;break;
 - case(0xb0):x=2;break;
 - case(0xd0):x=3;break;
 - case(0xe0):x=4;break;
 - }
 - while(a<50&&P1!=0xf0)//当按键按下的时间超过了500ms或者按键松开了就退出while循环
 - {
 - delay(1000);
 - a++;
 - }
 - }
 - }
 - int main()
 - {
 - lsa=0;
 - lsb=0;
 - lsc=0;//位选选中第一个数码管
 - P0=0x00;//第一个数码管先什么都不显示
 - while(1)
 - {
 - keyproc();
 - P0=zxm[(x-1)*4+y-1];//送入段选信息
 - }
 - return 0;
 - }
 
2、行扫描法
原文:https://blog.csdn.net/zxnsirius/article/details/51088946

-  
根据原理图
键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平,此时再来读取列线数据,发现列线读到的数据有低电平,数值为1011(0x0B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。转到S5键功能处理子程序就可以达到目的。/*
功能:矩阵键盘扫面,按键显示键值程序
作者:siriuszxn
*/
#include "reg51.h"
#define KEYPORT = P1unsigned char i;
unsigned char Keynum;
unsigned char Line; //行
unsigned char Mask;
unsigned char Col; //列
unsigned char ScanCode;unsigned char code psegs_table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共阳极数码管0-F
void delay_ms(unsigned int t) //ms延时程序
{
unsigned char i;
unsigned int x;
x=t;
while(x--)
{
for(i=0;i<113;i++);
}
}
/* 键盘扫描程序 */
void keyscan()
{
while (1) //循环扫描键盘
{
P1 = 0xff; //开始
Line = 1;
Mask = 0x01;for(i = 0; i < 4; i++)
{
P1 = ~Mask;ScanCode = P1 & 0xf0;
if (ScanCode != 0xf0)
{
delay_ms(5);
}ScanCode = P1 & 0xf0;
switch(ScanCode)
{
case 0xe0:Col=1;break;
case 0xd0:Col=2;break;
case 0xb0:Col=3;break;
case 0x70:Col=4;break;
default :Col=0;break;
}if (Col > 0)
{
//根据行列计算键值
Keynum = (Line - 1) * 4 + Col;
//通过P0口接数码管显示
P0 = psegs_table[Keynum-1];while(1)
{
ScanCode = P1 & 0xf0;
if(ScanCode == 0xf0)
{
break;
}
}
Mask <<= 1;
Line++;
}
}
}
}void main()
{
while(1)
{
keyscan();
}
}
STM32 >> 矩阵键盘(代码风格优美,简明易懂) -  
原文:https://blog.csdn.net/weixin_40973138/article/details/86607562
 
key.h
- /**
 - ******************************************************************************
 - * @file bsp_key.h
 - * @author Waao
 - * @version V1.0.0
 - * @date 23-Jan-2019
 - * @brief This file contains some board support package's definition for the KEY.
 - *
 - ******************************************************************************
 - * @attention
 - *
 - * None
 - *
 - ******************************************************************************
 - */
 - #ifndef __BSP_KEY_H_
 - #define __BSP_KEY_H_
 - #include <stm32f4xx.h>
 - #include <bsp_systick.h>
 - #include <bsp_usart.h>
 - // Column1, Column2, Column3, Column4
 - #define C1_PIN GPIO_Pin_2
 - #define C1_GPIO_PORT GPIOE
 - #define C1_GPIO_CLK RCC_AHB1Periph_GPIOE
 - #define C2_PIN GPIO_Pin_3
 - #define C2_GPIO_PORT GPIOE
 - #define C2_GPIO_CLK RCC_AHB1Periph_GPIOE
 - #define C3_PIN GPIO_Pin_4
 - #define C3_GPIO_PORT GPIOE
 - #define C3_GPIO_CLK RCC_AHB1Periph_GPIOE
 - #define C4_PIN GPIO_Pin_5
 - #define C4_GPIO_PORT GPIOE
 - #define C4_GPIO_CLK RCC_AHB1Periph_GPIOE
 - // Row1, Row2, Row3, Row4
 - #define R1_PIN GPIO_Pin_12
 - #define R1_GPIO_PORT GPIOB
 - #define R1_GPIO_CLK RCC_AHB1Periph_GPIOB
 - #define R2_PIN GPIO_Pin_13
 - #define R2_GPIO_PORT GPIOB
 - #define R2_GPIO_CLK RCC_AHB1Periph_GPIOB
 - #define R3_PIN GPIO_Pin_14
 - #define R3_GPIO_PORT GPIOB
 - #define R3_GPIO_CLK RCC_AHB1Periph_GPIOB
 - #define R4_PIN GPIO_Pin_15
 - #define R4_GPIO_PORT GPIOB
 - #define R4_GPIO_CLK RCC_AHB1Periph_GPIOB
 - // detect and output
 - #define DETECT_C1 GPIO_ReadInputDataBit(C1_GPIO_PORT, C1_PIN)
 - #define DETECT_C2 GPIO_ReadInputDataBit(C2_GPIO_PORT, C2_PIN)
 - #define DETECT_C3 GPIO_ReadInputDataBit(C3_GPIO_PORT, C3_PIN)
 - #define DETECT_C4 GPIO_ReadInputDataBit(C4_GPIO_PORT, C4_PIN)
 - #define DETECT_R1 GPIO_ReadInputDataBit(R1_GPIO_PORT, R1_PIN)
 - #define DETECT_R2 GPIO_ReadInputDataBit(R2_GPIO_PORT, R2_PIN)
 - #define DETECT_R3 GPIO_ReadInputDataBit(R3_GPIO_PORT, R3_PIN)
 - #define DETECT_R4 GPIO_ReadInputDataBit(R4_GPIO_PORT, R4_PIN)
 - // Keys
 - #define S1 0x77
 - #define S2 0xB7
 - #define S3 0xD7
 - #define S4 0xE7
 - #define S5 0x7B
 - #define S6 0xBB
 - #define S7 0xDB
 - #define S8 0xEB
 - #define S9 0x7D
 - #define S10 0xBD
 - #define S11 0xDD
 - #define S12 0xED
 - #define S13 0x7E
 - #define S14 0xBE
 - #define S15 0xDE
 - #define S16 0xEE
 - void GPIO_RCC_Config(void);
 - void ROCI_GPIO_Config(void);
 - void RICO_GPIO_Config(void);
 - void KEY_GPIO_ConfigAndDetect(void);
 - #endif
 
 有关输入输出管脚的选择可以多试验几组,有的管脚即使你配置成上拉输入,当你松开按键之后依然不会返回高电平,我在此就因为这个问题被卡了一阵子
关于我的矩阵键盘检测的原理简明阐述如下:
首先设置为行输出低电平,列上拉输入(即无外部干扰时保持高电平);
 检测到按键按下,此时通过检测列的电平情况从而得知哪一列有按键被按下;
 然后确定有按键被按下后,设置为列输出低电平,行上拉输入;
 通过检测行的电平情况从而得知哪一行有按键被按下;
 最后通过“不平行的两条直线相交于一点”原理,推知具体被按下的按键。
 key.c
- /**
 - ******************************************************************************
 - * @file bsp_key.c
 - * @author Waao
 - * @version V1.0.0
 - * @date 23-Jan-2019
 - * @brief This file contains some board support package's functions for the KEY.
 - *
 - ******************************************************************************
 - * @attention
 - *
 - * None
 - *
 - ******************************************************************************
 - */
 - #include <bsp_key.h>
 - /**
 - * @brief Initialize the RCC of the 8 GPIO line.
 - * @param None
 - * @retval None
 - */
 - void GPIO_RCC_Config(void)
 - {
 - RCC_AHB1PeriphClockCmd(C1_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(C2_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(C3_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(C4_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(R1_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(R2_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(R3_GPIO_CLK, ENABLE);
 - RCC_AHB1PeriphClockCmd(R4_GPIO_CLK, ENABLE);
 - }
 - /**
 - * @brief Initialize the Row out Column in.
 - * @param None
 - * @retval None
 - */
 - void ROCI_GPIO_Config(void)
 - {
 - GPIO_InitTypeDef GPIO_Structure;
 - //============ Column =============
 - GPIO_Structure.GPIO_Mode = GPIO_Mode_IN;
 - GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;
 - GPIO_Structure.GPIO_OType = GPIO_OType_PP;
 - GPIO_Structure.GPIO_PuPd = GPIO_PuPd_UP;
 - GPIO_Structure.GPIO_Pin = C1_PIN;
 - GPIO_Init(C1_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = C2_PIN;
 - GPIO_Init(C2_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = C3_PIN;
 - GPIO_Init(C3_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = C4_PIN;
 - GPIO_Init(C4_GPIO_PORT, &GPIO_Structure);
 - //============== Row ===============
 - GPIO_Structure.GPIO_Mode = GPIO_Mode_OUT;
 - GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;
 - GPIO_Structure.GPIO_OType = GPIO_OType_PP;
 - GPIO_Structure.GPIO_PuPd = GPIO_PuPd_DOWN;
 - GPIO_Structure.GPIO_Pin = R1_PIN;
 - GPIO_Init(R1_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = R2_PIN;
 - GPIO_Init(R2_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = R3_PIN;
 - GPIO_Init(R3_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = R4_PIN;
 - GPIO_Init(R4_GPIO_PORT, &GPIO_Structure);
 - GPIO_ResetBits(R1_GPIO_PORT, R1_PIN);
 - GPIO_ResetBits(R2_GPIO_PORT, R2_PIN);
 - GPIO_ResetBits(R3_GPIO_PORT, R3_PIN);
 - GPIO_ResetBits(R4_GPIO_PORT, R4_PIN);
 - }
 - /**
 - * @brief Initialize the Row in Column out.
 - * @param None
 - * @retval None
 - */
 - void RICO_GPIO_Config(void)
 - {
 - GPIO_InitTypeDef GPIO_Structure;
 - //============== Row ==================
 - GPIO_Structure.GPIO_Mode = GPIO_Mode_IN;
 - GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;
 - GPIO_Structure.GPIO_OType = GPIO_OType_PP;
 - GPIO_Structure.GPIO_PuPd = GPIO_PuPd_UP;
 - GPIO_Structure.GPIO_Pin = R1_PIN;
 - GPIO_Init(R1_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = R2_PIN;
 - GPIO_Init(R2_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = R3_PIN;
 - GPIO_Init(R3_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = R4_PIN;
 - GPIO_Init(R4_GPIO_PORT, &GPIO_Structure);
 - //============ Column ================
 - GPIO_Structure.GPIO_Mode = GPIO_Mode_OUT;
 - GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;
 - GPIO_Structure.GPIO_OType = GPIO_OType_PP;
 - GPIO_Structure.GPIO_PuPd = GPIO_PuPd_DOWN;
 - GPIO_Structure.GPIO_Pin = C1_PIN;
 - GPIO_Init(C1_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = C2_PIN;
 - GPIO_Init(C2_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = C3_PIN;
 - GPIO_Init(C3_GPIO_PORT, &GPIO_Structure);
 - GPIO_Structure.GPIO_Pin = C4_PIN;
 - GPIO_Init(C4_GPIO_PORT, &GPIO_Structure);
 - GPIO_ResetBits(C1_GPIO_PORT, C1_PIN);
 - GPIO_ResetBits(C2_GPIO_PORT, C2_PIN);
 - GPIO_ResetBits(C3_GPIO_PORT, C3_PIN);
 - GPIO_ResetBits(C4_GPIO_PORT, C4_PIN);
 - }
 - /**
 - * @brief Configure the GPIO, and detect whether the key was pressed down
 - * @param None
 - * @retval None
 - */
 - void KEY_GPIO_ConfigAndDetect(void)
 - {
 - u8 TEMP_COMBINE = 0, TEMP_ROCI = 0, TEMP_RICO = 0;
 - GPIO_RCC_Config();
 - printf("\nWhy so serious ?\tThe game just begin!");
 - while(1)
 - {
 - ROCI_GPIO_Config();
 - TEMP_ROCI = (u8)(((u8)DETECT_C1) << 3) |
 - (((u8)DETECT_C2) << 2) |
 - (((u8)DETECT_C3) << 1) |
 - (((u8)DETECT_C4) << 0);
 - if(TEMP_ROCI != 0x0f)
 - {
 - Delay(1000); // Eliminate the shaking. The parameter's unit is 10us
 - if(TEMP_ROCI != 0x0f) // Ensure one of the keys was pressed down indeed.
 - {
 - RICO_GPIO_Config();
 - TEMP_RICO = (u8)(((u8)DETECT_R1) << 3) |
 - (((u8)DETECT_R2) << 2) |
 - (((u8)DETECT_R3) << 1) |
 - (((u8)DETECT_R4) << 0);
 - TEMP_COMBINE = (u8)((TEMP_ROCI << 4) | TEMP_RICO); // Combine the two situation and we can know which key was pressed down.
 - switch(TEMP_COMBINE)
 - {
 - case S1:
 - printf("\nS1 was pressed down!");
 - break;
 - case S2:
 - printf("\nS2 was pressed down!");
 - break;
 - case S3:
 - printf("\nS3 was pressed down!");
 - break;
 - case S4:
 - printf("\nS4 was pressed down!");
 - break;
 - case S5:
 - printf("\nS5 was pressed down!");
 - break;
 - case S6:
 - printf("\nS6 was pressed down!");
 - break;
 - case S7:
 - printf("\nS7 was pressed down!");
 - break;
 - case S8:
 - printf("\nS8 was pressed down!");
 - break;
 - case S9:
 - printf("\nS9 was pressed down!");
 - break;
 - case S10:
 - printf("\nS10 was pressed down!");
 - break;
 - case S11:
 - printf("\nS11 was pressed down!");
 - break;
 - case S12:
 - printf("\nS12 was pressed down!");
 - break;
 - case S13:
 - printf("\nS13 was pressed down!");
 - break;
 - case S14:
 - printf("\nS14 was pressed down!");
 - break;
 - case S15:
 - printf("\nS15 was pressed down!");
 - break;
 - case S16:
 - printf("\nS16 was pressed down!");
 - break;
 - default:
 - break;
 - }
 - while(TEMP_RICO != 0x0F)
 - {
 - TEMP_RICO = (u8)(((u8)DETECT_R1)<<3) |
 - (((u8)DETECT_R2)<<2) |
 - (((u8)DETECT_R3)<<1) |
 - (((u8)DETECT_R4)<<0);
 - }
 - }
 - }
 - }
 - }
 
