stm32f103zet6 矩阵键盘代码
在正点原子精英版上测试通过。
matrix_key.c 驱动文件
#include "matrix_key.h"
#include "delay.h"
#include "sys.h"
/************************************
按键表盘为: 1 2 3 4
5 6 7 8
9 0 A B
C D E F
************************************/
unsigned char Y1,Y2,Y3,Y4;
void Matrix_Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC|RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
/*****************************4行输出*********************************************/
GPIO_InitStructure.GPIO_Pin = X1_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = X2_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = X3_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;
GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);
/**************************************4列输入*************************************/
GPIO_InitStructure.GPIO_Pin = Y1_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Y2_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Y3_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;
GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);
}
int Matrix_Key_Scan(void)
{
uchar KeyVal = KEY_ERR;
static char key_down = 0;
GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN); //先让X1输出高
GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN); //先让X2输出高
GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN); //先让X3输出高
GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN); //先让X4输出高
if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
{
delay_ms(10);//去抖动
if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
{
if (key_down == 0)
{
key_down = 1; //重复按标志位
GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=4;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=8;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal='B';
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal='F';
/**************************************************/
GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=3;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=7;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal='A';
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal='E';
/**************************************************/
GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=2;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=6;
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal=0;
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal='D';
/**************************************************/
GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);
Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
KeyVal=1;
if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
KeyVal=5;
if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
KeyVal='C';
if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
KeyVal=9;
}
}
}
else
{
key_down = 0; //没有检测到有按键按下,则让连按标志位归0
}
return KeyVal;
}
void Matrix_Key_Test(void)
{
int num;
num = Matrix_Key_Scan();
switch(num)
{
case KEY_ERR:break;
case 0: printf("0\r\n"); break;
case 1: printf("1\r\n"); break;
case 2: printf("2\r\n"); break;
case 3: printf("3\r\n"); break;
case 4: printf("4\r\n"); break;
case 5: printf("5\r\n"); break;
case 6: printf("6\r\n"); break;
case 7: printf("7\r\n"); break;
case 8: printf("8\r\n"); break;
case 9: printf("9\r\n"); break;
case 'A': printf("A\r\n"); break;
case 'B': printf("B\r\n"); break;
case 'C': printf("C\r\n"); break;
case 'D': printf("D\r\n"); break;
case 'E': printf("E\r\n"); break;
case 'F': printf("F\r\n"); break;
}
}
matrix_key.h 头文件
#ifndef MATRIX_KEY_H
#define MATRIX_KEY_H
#include
#include "usart.h"
#include "sys.h"
#define uint unsigned int
#define uchar unsigned char
//8个引脚 4个为行 4个为列
//行输出端口定义
#define X1_GPIO_PORT GPIOA
#define X2_GPIO_PORT GPIOA
#define X3_GPIO_PORT GPIOA
#define X4_GPIO_PORT GPIOA
//列输入端口定义
#define Y1_GPIO_PORT GPIOA
#define Y2_GPIO_PORT GPIOA
#define Y3_GPIO_PORT GPIOA
#define Y4_GPIO_PORT GPIOA
//行输出引脚定义
#define X1_GPIO_PIN GPIO_Pin_0
#define X2_GPIO_PIN GPIO_Pin_1
#define X3_GPIO_PIN GPIO_Pin_2
#define X4_GPIO_PIN GPIO_Pin_3
//列输入引脚定义
#define Y1_GPIO_PIN GPIO_Pin_4
#define Y2_GPIO_PIN GPIO_Pin_5
#define Y3_GPIO_PIN GPIO_Pin_6
#define Y4_GPIO_PIN GPIO_Pin_7
//行输出时钟定义
#define X1_RCC RCC_APB2Periph_GPIOA
#define X2_RCC RCC_APB2Periph_GPIOA
#define X3_RCC RCC_APB2Periph_GPIOA
#define X4_RCC RCC_APB2Periph_GPIOA
//列输入时钟定义
#define Y1_RCC RCC_APB2Periph_GPIOA
#define Y2_RCC RCC_APB2Periph_GPIOA
#define Y3_RCC RCC_APB2Periph_GPIOA
#define Y4_RCC RCC_APB2Periph_GPIOA
//移植代码只需要修改上面的端口和引脚和时钟即可,下面的代码不用修改。
//矩阵键盘所用的8个引脚可连续可不连续,看实际需要和个人爱好自己定义。
#define KEY_ERR 255
void Matrix_Key_Init(void);
int Matrix_Key_Scan(void);
void Matrix_Key_Test(void) ;
#endif
main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "matrix_key.h"
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
Matrix_Key_Init();
printf("ok\r\n");
while(1)
{
delay_ms(50);
Matrix_Key_Test();
}
}