组内的小伙伴们从暑假开始的时候开始学习32也学了快20天了,昨天作为一个小检测吧,让他们焊了一个3*3的矩阵键盘然后写了键盘的驱动,虽然中间的过程有些曲折,但最后结果还是可以的,每个人都写出来了。
我也画了键盘的原理图以及接线图,并且也写了键盘的驱动,在博客上记录一下吧。
矩阵键盘的原理就是分行和列扫描,来获知按下按键的行数和列数,然后得到按下按键的键值
矩阵键盘的原理图及接线图如下:
因为四脚的微动按键的同一排引脚是相连的,相当于是一个同一个引脚,所以利用这个有点会大大简化我们的电路,不用做太多的飞线。
接线效果图如下
矩阵键盘的扫描原理为,先让三个横行或者三个竖列输出高电平,另外三个为输入模式,若扫描到高电平,则表示该行或该列有按键按下,接着切换输入输出,扫描另外三个,得到另外的坐标,由此确定按键按下的位置。
F4的代码如下:
key.h
#ifndef __KEY_H
#define __KEY_H
#include “sys.h”
//行操作宏定义
#define Row1_Write PAout(0)
#define Row2_Write PAout(2)
#define Row3_Write PAout(3)
#define Row1_Read PAin(0)
#define Row2_Read PAin(2)
#define Row3_Read PAin(3)
//列操作宏定义
#define Col1_Write PAout(7)
#define Col2_Write PAout(6)
#define Col3_Write PAout(4)
#define Col1_Read PAin(7)
#define Col2_Read PAin(6)
#define Col3_Read PAin(4)
#define PIN_OUT(x) {GPIOA-》MODER&=~(3《《((x)*2));GPIOA-》MODER|=1《《((x)*2);} //将IO口配置为输出
#define PIN_IN(x) {GPIOA-》MODER&=~(3《《((x)*2));GPIOA-》MODER|=0《《((x)*2);} //将IO口配置为输入
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8); //按键扫描函数
#endif
key.c
#include “key.h”
#include “delay.h”
#include “usart.h”
void KEY_Init(void)
{
RCC-》AHB1ENR|=1《《0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN0|PIN2|PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); //PA0PA2PA3设置为输入
GPIO_Set(GPIOA,PIN4|PIN6|PIN7,GPIO_MODE_OUT,0,0,GPIO_PUPD_PU); //推挽输出
}
//按键处理函数
u8 KEY_Scan(u8 mode)
{
u8 res[4][4]={{0,0,0,0},{0,1,2,3},{0,4,5,6},{0,7,8,9}};
u8 row=0,col=0;
Col1_Write=1;
Col2_Write=1;
Col3_Write=1;
//检测行
if(Row1_Read==1||Row2_Read==1||Row3_Read==1)
{
delay_ms(10);//去抖动
if(Row1_Read==1)
row=1;
else if(Row2_Read==1)
row=2;
else if(Row3_Read==1)
row=3;
}
else
return 0; //无按键按下
//改变输入输出模式
Col1_Write=0;
Col2_Write=0;
Col3_Write=0;
PIN_OUT(0);
PIN_OUT(2);
PIN_OUT(3);
PIN_IN(4);
PIN_IN(6);
PIN_IN(7);
Row1_Write=1;
Row2_Write=1;
Row3_Write=1;
//检测列
if(Col1_Read==1)
col=1;
else if(Col2_Read==1)
col=2;
else if(Col3_Read==1)
col=3;
//还原IO口
PIN_OUT(4);
PIN_OUT(6);
PIN_OUT(7);
PIN_IN(0);
PIN_IN(2);
PIN_IN(3);
if(row!=0&&col!=0)
{
return res[row][col];
}
else
return 0;
}
主函数,扫描后在串口打印键值
#include “sys.h”
#include “delay.h”
#include “key.h”
#include “usart.h”
#include “led.h”
int main(void)
{
u8 key;
Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
uart_init(84,115200);
delay_init(168); //延时初始化
KEY_Init(); //初始化与按键连接的硬件接口
LED_Init();
LED0=0;
while(1)
{
LED0=1;
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case 1:
printf(“1rn”);
break;
case 2:
printf(“2rn”);
break;
case 3:
printf(“3rn”);
break;
case 4:
printf(“4rn”);
break;
case 5:
printf(“5rn”);
break;
case 6:
printf(“6rn”);
break;
case 7:
printf(“7rn”);
break;
case 8:
printf(“8rn”);
break;
case 9:
printf(“9rn”);
break;
}
}
LED0=0;
}
}
组内的小伙伴们从暑假开始的时候开始学习32也学了快20天了,昨天作为一个小检测吧,让他们焊了一个3*3的矩阵键盘然后写了键盘的驱动,虽然中间的过程有些曲折,但最后结果还是可以的,每个人都写出来了。
我也画了键盘的原理图以及接线图,并且也写了键盘的驱动,在博客上记录一下吧。
矩阵键盘的原理就是分行和列扫描,来获知按下按键的行数和列数,然后得到按下按键的键值
矩阵键盘的原理图及接线图如下:
因为四脚的微动按键的同一排引脚是相连的,相当于是一个同一个引脚,所以利用这个有点会大大简化我们的电路,不用做太多的飞线。
接线效果图如下
矩阵键盘的扫描原理为,先让三个横行或者三个竖列输出高电平,另外三个为输入模式,若扫描到高电平,则表示该行或该列有按键按下,接着切换输入输出,扫描另外三个,得到另外的坐标,由此确定按键按下的位置。
F4的代码如下:
key.h
#ifndef __KEY_H
#define __KEY_H
#include “sys.h”
//行操作宏定义
#define Row1_Write PAout(0)
#define Row2_Write PAout(2)
#define Row3_Write PAout(3)
#define Row1_Read PAin(0)
#define Row2_Read PAin(2)
#define Row3_Read PAin(3)
//列操作宏定义
#define Col1_Write PAout(7)
#define Col2_Write PAout(6)
#define Col3_Write PAout(4)
#define Col1_Read PAin(7)
#define Col2_Read PAin(6)
#define Col3_Read PAin(4)
#define PIN_OUT(x) {GPIOA-》MODER&=~(3《《((x)*2));GPIOA-》MODER|=1《《((x)*2);} //将IO口配置为输出
#define PIN_IN(x) {GPIOA-》MODER&=~(3《《((x)*2));GPIOA-》MODER|=0《《((x)*2);} //将IO口配置为输入
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8); //按键扫描函数
#endif
key.c
#include “key.h”
#include “delay.h”
#include “usart.h”
void KEY_Init(void)
{
RCC-》AHB1ENR|=1《《0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN0|PIN2|PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); //PA0PA2PA3设置为输入
GPIO_Set(GPIOA,PIN4|PIN6|PIN7,GPIO_MODE_OUT,0,0,GPIO_PUPD_PU); //推挽输出
}
//按键处理函数
u8 KEY_Scan(u8 mode)
{
u8 res[4][4]={{0,0,0,0},{0,1,2,3},{0,4,5,6},{0,7,8,9}};
u8 row=0,col=0;
Col1_Write=1;
Col2_Write=1;
Col3_Write=1;
//检测行
if(Row1_Read==1||Row2_Read==1||Row3_Read==1)
{
delay_ms(10);//去抖动
if(Row1_Read==1)
row=1;
else if(Row2_Read==1)
row=2;
else if(Row3_Read==1)
row=3;
}
else
return 0; //无按键按下
//改变输入输出模式
Col1_Write=0;
Col2_Write=0;
Col3_Write=0;
PIN_OUT(0);
PIN_OUT(2);
PIN_OUT(3);
PIN_IN(4);
PIN_IN(6);
PIN_IN(7);
Row1_Write=1;
Row2_Write=1;
Row3_Write=1;
//检测列
if(Col1_Read==1)
col=1;
else if(Col2_Read==1)
col=2;
else if(Col3_Read==1)
col=3;
//还原IO口
PIN_OUT(4);
PIN_OUT(6);
PIN_OUT(7);
PIN_IN(0);
PIN_IN(2);
PIN_IN(3);
if(row!=0&&col!=0)
{
return res[row][col];
}
else
return 0;
}
主函数,扫描后在串口打印键值
#include “sys.h”
#include “delay.h”
#include “key.h”
#include “usart.h”
#include “led.h”
int main(void)
{
u8 key;
Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
uart_init(84,115200);
delay_init(168); //延时初始化
KEY_Init(); //初始化与按键连接的硬件接口
LED_Init();
LED0=0;
while(1)
{
LED0=1;
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case 1:
printf(“1rn”);
break;
case 2:
printf(“2rn”);
break;
case 3:
printf(“3rn”);
break;
case 4:
printf(“4rn”);
break;
case 5:
printf(“5rn”);
break;
case 6:
printf(“6rn”);
break;
case 7:
printf(“7rn”);
break;
case 8:
printf(“8rn”);
break;
case 9:
printf(“9rn”);
break;
}
}
LED0=0;
}
}
举报