本周扩展了一下STM32的按键个数。
矩阵键盘原理:通过六个引脚分别控制3*3矩阵键盘的三个行和三个列
实现:分别给按键标号1-9,按下按键后,通过串口输出按键的标号即可。
以下为代码实现:
分两次扫描计算出最终的按键号
key.c文件
#include "key.h"
#include "delay.h"
#include "sys.h"
//按键初始化函数
//PB5-7设置成输入 PB8-10设置成输出
void KEY_Init1(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
JTAG_Set(SWD_ENABLE); //关闭JTAG,开启SWD
GPIOB->CRL&=0X000FFFFF; //PB5-7设置成输入
GPIOB->CRL|=0X88800000;
GPIOB->CRH&=0XFFFFF000; //PB8-10设置成输出
GPIOB->CRH|=0X00000333;
}
void KEY_Init2(void)
{
GPIOB->CRL&=0X000FFFFF; //PB5-7设置成输出
GPIOB->CRL|=0X33300000;
GPIOB->CRH&=0XFFFFF000; //PB8-10设置成输入
GPIOB->CRH|=0X00000888;
}
//按键扫描函数
//默认优先级行 列为1 2 3
u8 KEY_Scan(u8 mode)
{
u8 l=0,h=0;
static u8 key_con=1; //按键按松开标志
if(mode) key_con=1; //支持连按
KEY_ROW_out1=0; //行输出置低
KEY_ROW_out2=0;
KEY_ROW_out3=0;
KEY_Init1();
KEY_ROL_out1=1; //列输出置高
KEY_ROL_out2=1;
KEY_ROL_out3=1;
if(key_con&&(KEY_ROW_in1==1||KEY_ROW_in2==1||KEY_ROW_in3==1)) //检测按下的按键所在行
{
delay_ms(10);
key_con=0;
if(KEY_ROW_in1==1) h=1; //返回行值
else if(KEY_ROW_in2==1) h=2;
else if(KEY_ROW_in3==1) h=3;
}
else if(KEY_ROW_in1==0&&KEY_ROW_in2==0&&KEY_ROW_in3==0) //无按键按下
{
key_con=1;
return 0;
}
KEY_ROL_out1=0; //二次扫描 列输出置低
KEY_ROL_out2=0;
KEY_ROL_out3=0;
KEY_Init2();
KEY_ROW_out1=1; //行输出置高
KEY_ROW_out2=1;
KEY_ROW_out3=1;
if(KEY_ROL_in1==1||KEY_ROL_in2==1||KEY_ROL_in3==1) //检测按下的按键所在列
{
delay_ms(10);
if(KEY_ROL_in1==1) l=(h-1)*3+1;
else if(KEY_ROL_in2==1) l=(h-1)*3+2;
else if(KEY_ROL_in3==1) l=(h-1)*3+3;
}
return l;
}
key.h文件
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY_ROW_in1 PBin(5)
#define KEY_ROW_in2 PBin(6)
#define KEY_ROW_in3 PBin(7)
#define KEY_ROL_out1 PBout(8)
#define KEY_ROL_out2 PBout(9)
#define KEY_ROL_out3 PBout(10)
#define KEY_ROW_out1 PBout(5)
#define KEY_ROW_out2 PBout(6)
#define KEY_ROW_out3 PBout(7)
#define KEY_ROL_in1 PBin(8)
#define KEY_ROL_in2 PBin(9)
#define KEY_ROL_in3 PBin(10)
void KEY_Init1(void); //IO初始化
void KEY_Init2(void);
u8 KEY_Scan(u8 mode);
#endif
main.c文件
#include "delay.h"
#include "led.h"
int main(void)
{
u8 key=0;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
//LED_Init(); //初始化与LED连接的硬件接口
uart_init(72,9600);
KEY_Init1();
while(1)
{
key=KEY_Scan(0);
if(key!=0)
{
printf("%d\r\n",key);
}
key=0;
delay_ms(100);
}
}