【STM32】4*4鍵盤輸入(附代碼、可直接使用)

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");
        }
    }
}
發佈了21 篇原創文章 · 獲贊 76 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章