【STM32】4*4键盘输入(附代码、可直接使用)

STM32/Raspberry Pi 专栏收录该内容
5 篇文章 0 订阅

STM32的4*4键盘输入(附代码、数字键盘通用)


博主使用的是淘宝上$2.5的4*4数字键盘(单片机外扩键盘),键盘规格不影响代码的使用(只要是4x4的键盘)。

另外说明:

1、4X4键盘的原理可直接百度搜得,在此不赘述。

2、STM32引脚的连接方式在GPIO初始化代码中有所说明。

3、此文章代码内容从博主参赛所用的工程文件中摘录而出,但这并不影响读者理解和直接使用。

以下为key.h文件中的内容:

#ifndef __KEY_H
#define __KEY_H

#include <stm32f10x.h>
#include "usart.h"
#include "delay.h"


#define uint unsigned int
#define uchar unsigned char

void Key_Config(void);
unsigned char KeyScan(void);//
void key_value_process(void);
extern unsigned char KEY_VALUE;
extern unsigned char state_flag;
extern unsigned char press_count;//按键计数
extern u8 uart2_send_buf[10];//串口2发送缓冲区,固定9个字节
#endif

以下为key.c文件中的内容:

#include "key.h"
#include "delay.h"
#include "usart.h"
unsigned char KEY_VALUE = 0XFF;
unsigned char state_flag = 0; //系统状态变量,1--6分别为6个不同的功能
unsigned char press_count = 0; //按键计数
u8 uart2_send_buf[10];//串口2发送缓冲区,固定9个字节
/**
** PB5-PB8,列,输出。 PB10-PB14,行,输入
//阿汪先生的博客
**/
void Key_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    /********4列输出*********/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /********4行输入*********/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
unsigned char KeyScan(void)               		         //键盘扫描函数
{
    u8 KeyVal;

    GPIO_Write(GPIOB, (GPIOB->ODR & 0xf0ff | 0x0f00));	 //先让PB8到PB11全部输出高。

    if((GPIOB->IDR & 0xf000) == 0x0000)
        return 0xff;
    else
    {
        delay_ms(5);    //延时5ms去抖动
        if((GPIOB->IDR & 0xf000) == 0x0000)
            return 0Xff;//未检测到按键
    }

    GPIO_Write(GPIOB, (GPIOB->ODR & 0xf0ff | 0x0100));	//让PB11到PB8输出二进制的0001.
    switch(GPIOB->IDR & 0xf000)
    {
    case 0x1000:
        KeyVal = 1;
        break;
    case 0x2000:
        KeyVal = 4;
        break;
    case 0x4000:
        KeyVal = 7;
        break;
    case 0x8000:
        KeyVal = 10;
        break;
    }
    while((GPIOB->IDR & 0xf000)	> 0);     //等待按键释放
    
	//阿汪先生的博客
	
    GPIO_Write(GPIOB, (GPIOB->ODR & 0xf0ff | 0x0200));	//让PB11到PB8输出二进制的0010.
    switch(GPIOB->IDR & 0xf000)		        //对PB12到PB15的值进行判断,以输出不同的键值。
    {
    case 0x1000:
        KeyVal = 2;
        break;
    case 0x2000:
        KeyVal = 5;
        break;
    case 0x4000:
        KeyVal = 8;
        break;
    case 0x8000:
        KeyVal = 0;
        break;
    }
    while((GPIOB->IDR & 0xf000)	> 0);

    GPIO_Write(GPIOB, (GPIOB->ODR & 0xf0ff | 0x0400));	//让PB11到PB8输出二进制的0100.
    switch(GPIOB->IDR & 0xf000)		        //对PB12到PB15的值进行判断,以输出不同的键值。
    {
    case 0x1000:
        KeyVal = 3;
        break;
    case 0x2000:
        KeyVal = 6;
        break;
    case 0x4000:
        KeyVal = 9;
        break;
    case 0x8000:
        KeyVal = 11;
        break;
    }
    while((GPIOB->IDR & 0xf000)	> 0);

    GPIO_Write(GPIOB, (GPIOB->ODR & 0xf0ff | 0x0800));	//让PB11到PB8输出二进制的1000.
    switch(GPIOB->IDR & 0xf000)		        //对PB12到PB15的值进行判断,以输出不同的键值。
    {
    case 0x1000:
        KeyVal = 12;
        break;
    case 0x2000:
        KeyVal = 13;
        break;
    case 0x4000:
        KeyVal = 14;
        break;
    case 0x8000:
        KeyVal = 15;
        break;
    }
    while((GPIOB->IDR & 0xf000)	> 0);
    
//阿汪先生的博客

    return KeyVal;
}
/*键盘数据处理函数*/             		//该函数可根据工程目的进行修改
void key_value_process(void)
{
    if(state_flag != 0)//非空闲状态
    {
        switch(state_flag)
        {
        case 2://功能2
            uart2_send_buf[press_count + 2]=KEY_VALUE;//存入键值
            press_count++;
            break;
        case 3://功能3
            uart2_send_buf[press_count + 2]=KEY_VALUE;//存入键值
            press_count++;
            break;
        default:

            state_flag=0;
            printf("key_press_error1\r\n");
        }
    }
    else
    {
        switch(KEY_VALUE)
        {
        case 0x0a:
            state_flag = 1; //基本功能1
            uart2_send_buf[1]=0x01;
            break;
        case 0x0b:
            state_flag = 2; //基本功能2
            uart2_send_buf[1]=0x02;
            break;
        case 0x0c:
            state_flag = 3; //基本功能3
            uart2_send_buf[1]=0x03;
            break;
        case 0x0d:
            state_flag = 4; //基本功能4
            uart2_send_buf[1]=0x04;
            break;
        case 0x0e:
            state_flag = 5; //基本功能5
            uart2_send_buf[1]=0x05;
            break;
        case 0x0f:
            state_flag = 6; //基本功能6
            uart2_send_buf[1]=0x06;
            break;
        default:
            state_flag=0;
            printf("key_press_error0\r\n");
        }
    }
}
  • 10
    点赞
  • 1
    评论
  • 67
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值