STM32操作矩阵键盘的两种方法——扫描和中断

STM32操作矩阵键盘的两种⽅法——扫描和中断
⽬录
最近在准备电赛,有⼀道题要求设计⼀个简易的信号发⽣器,需要⽤到矩阵键盘来输⼊待⽣成信号的类型、频率和幅值等参数,因此写下本⽂来总结我试验过的单⽚机操作矩阵键盘的两种⽅法。
⼀、矩阵键盘的结构和原理
矩阵键盘的实物可能长这样:
也可能长这样:
不管它们外表什么样,它们的内部结构都⼤同⼩异:
每⼀个矩阵键盘有8个信号端⼝,其中四个与⾏相连,剩下四个与列相连。当某⼀个按键按下时,对应⾏与列的端⼝就通过按键短接起来了。如何利⽤这个特性来让STM32判断是哪个按键按下呢?下⾯笔者总结了常见的两种⽅法。
⼆、扫描式矩阵键盘的原理和实现
⾸先明确⼀点,当STM32的GPIO配置成开漏输出+上拉电阻时,具有准双向IO的功能。
利⽤扫描的⽅式判断键盘按下的基本思想为:先把⾏全部置低,列全部置⾼,读取每⾏的电平,为⾼的即为按下的⾏;然后把列全部置低,⾏全部置⾼,读取每列的电平,为⾼的即为按下的列。代码如下:
//按键初始化函数
//PA0~3接1~4⾏,PA4~7接1~4列
void KEY_Init(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Pin|=  GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化
}
//按键处理函数
//返回按键值
/
*mode =1代表⽀持连按,mode = 0代表不⽀持联连按*/
u8 matrixkey(int mode){
u8 row =0;
u8 column =0;
static u8 key =1;
GPIO_Write(GPIOA,0x0F);
if(mode)key =1;
if(key&&(GPIO_ReadInputData(GPIOA)&0xFF)!=0x0F){//说明有按键按下
delay_ms(10);//按下消抖
column =GPIO_ReadInputData(GPIOA)&0x0F;//列数
key =0;
}
else if((GPIO_ReadInputData(GPIOA)&0XFF)==0X0F){//说明⽆按键按下
delay_ms(10);//松⼿消抖
key =1;
}
return row+column;//如:返回11011011代表第三⾏第⼆列
}
//矩阵键盘选择所实现功能的函数
//⼊⼝参数:按下的键值
//出⼝参数:⽆
void matrixkey_function(u8 key)
{
if(key)
{
switch(key)
{
//第⼀⾏
case0xee:break;
case0xde:break;
case0xbe:break;
case0x7e:break;
//第⼆⾏
case0xed:break;
case0xbd:break;
case0xdd:break;
case0x7d:break;
//第三⾏
case0xeb:break;
case0xdb:break;
case0xbb:break;
case0x7b:break;
//第四⾏
case0xe7:break;
case0xd7:break;
case0xb7:break;
case0x77:break;
}
}
}
三、中断式矩阵键盘的原理和实现
同样,⾸先明确GPIO的配置。中断⽅式下,应该将四⾏配置为推挽输出,四列配置为输⼊+上拉电阻+下降沿中断模式,当然,⾏列互换也是可以的。
中断式矩阵键盘的基本思想是,初始化时将四⾏拉低,当有按键按下时,这⼀列对应的端⼝会检测到下降沿,进⽽程序进⼊该列的中断服务函数,在中断服务函数中,将四⾏拉⾼,然后依次拉低每⼀⾏,同时检测该列的端⼝是否为低电平,如果为低电平,则证明是该⾏该列按下。代码如下:
/
/矩阵键盘端⼝初始化
//PF1~4接列 PF5~8接⾏
void MatrixKEY_Init(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//通⽤输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
再生油GPIO_ResetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//初始化输出置低
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输⼊模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;//上拉
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIOF1234
}
*/
//第⼀⾏
void EXTI1_IRQHandler(void){
u8 i;
delay_ms(50);
if(PFin(1)==0){/第⼀⾏
EXTIX1_4_disable();//关闭矩阵键盘的中断
for(i=5;i<9;i++){
GPIO_SetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为⾼电平PFout(i)=0;
delay_ms(50);
if(PFin(1)==0){
switch(i){
case(5):
num=1;
break;
case(6):
num=2;
break;
case(7):
num=3;
break;
case(8):
num=12;
break;
default:num=16;
}}
}
GPIO_ResetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为低电平EXTIX1_4_enable();
}
EXTI_ClearITPendingBit(EXTI_Line1);//清除中断标志位*/
}
void EXTI2_IRQHandler(void){
u8 i;
delay_ms(50);
if(PFin(2)==0){/第⼆⾏
EXTIX1_4_disable();//关闭矩阵键盘的中断ecall测试
for(i=5;i<9;i++)
{
GPIO_SetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为⾼电平PFout(i)=0;
delay_ms(50);
if(PFin(2)==0){
switch(i){
case(5):
num=4;
break;
case(6):
num=13;
break;
default:num=16;
}}
}
GPIO_ResetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为低电平EXTIX1_4_enable();
}
EXTI_ClearITPendingBit(EXTI_Line2);//清除中断标志位*/
}
void EXTI3_IRQHandler(void){
u8 i;
delay_ms(50);
if(PFin(3)==0){第三⾏
EXTIX1_4_disable();//关闭矩阵键盘的中断
for(i=5;i<9;i++)
{
GPIO_SetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为⾼电平PFout(i)=0;
delay_ms(50);
if(PFin(3)==0){
switch(i){
case(5):
num=7;
break;
case(6):
num=8;
break;
case(7):
num=9;
break;
case(8):
num=14;
break;
siro2246default: num=16;
}}
}
GPIO_ResetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为低电平EXTIX1_4_enable();
}
EXTI_ClearITPendingBit(EXTI_Line3);//清除中断标志位*/
}
void EXTI4_IRQHandler(void){
u8 i;
delay_ms(50);
if(PFin(4)==0){第四列
EXTIX1_4_disable();//关闭矩阵键盘的中断
for(i=5;i<9;i++)oju
{
GPIO_SetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为⾼电平PFout(i)=0;
delay_ms(50);
num=0;
break;
case(7):
num=11;
break;
case(8):
num=15;
break;
default:num=16;
}}
}
GPIO_ResetBits(GPIOF,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//置为低电平EXTIX1_4_enable();
}
EXTI_ClearITPendingBit(EXTI_Line4);//清除中断标志位*/
}
//中断优先级配置
void NVICx_Init(void)
{
NVIC_InitTypeDef  NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//外部中断1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;//⼦优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断通道使能
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中断2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;//抢占优先级2
室内垃圾桶
扫地机滚刷NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;//⼦优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断通道使能
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//外部中断3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;//⼦优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断通道使能
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;//⼦优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断通道使能
NVIC_Init(&NVIC_InitStructure);
}
//外部中断初始化程序
//初始化PF1~4为中断输⼊.
void EXTIX_Init(void)
{
EXTI_InitTypeDef  EXTI_InitStructure;

本文发布于:2024-09-21 22:06:00,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/329883.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:中断   键盘   矩阵   按键   低电平   置为   总结   代表
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议