说明
矩阵键盘的按键识别方法
矩阵键盘的键识别方法来自“简单日记”的选择和推荐。在学习矩阵键盘时,经常需要学习矩阵键盘的按键识别方法,那么矩阵键盘的按键识别方法有哪些呢?小编带您了解。
方法1:线扫描方法
1、确定键盘上是否有按键,并将所有行p 1. 4-p 1. 7设置为低电平,当然p 1. 0-p 1. 3为高电平(也许这些引脚已在芯片内部上拉),然后检查列线的状态。只要一列的电平为低,就表示按下了键盘上的一个键,而闭合键位于低电平线和4行线相交的4个键之中。如果所有列行都处于高电平,则无需在键盘中按任何键。
2、确定关闭键的位置在确认已按下某个键之后,您可以进入确定特定关闭键的过程。方法是:依次将行线设置为低电平,即当某行线设置为低电平时,其他线为高电平。确认某行的位置为低电平后,逐行检测各列线的电平状态。如果列为低,则列线和行线的交点处设置为低的按钮是关闭的按钮。
方法2:首先从端口p1的高四位输出低电平,从端口p1的低四位输出高电平,然后从端口p1的低四位读取键盘状态。然后从端口p1的低四位输出低电平,从端口p1的高四位输出高电平,并从端口p1的高四位读取键盘状态。结合两个读取结果,以获取当前按钮的功能代码。
矩阵键盘扫描程序
使用芯片STM8S003
使用的端口:PD2〜PD6,PA1〜PA3
其中,PD3〜PD6是输出,PA1〜PA3 / PD2是输入(默认上拉)
/ *
PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
PD6 PD5 PD4 PD3 PD2 PA3 PA2 PA1
* /
过程如下:
/ *添加包含芯片的头文件* /
#include《 iostm8s103f 3. h》
易失性无符号字符CF [4]; //按键触发标志(表示4列,每列位于同一行
//值相同,但列标签不同以区分不同列的键)
volatile unsigned char Cont [4];
unsigned char KeyVal; //键值
//无符号字符KeyOut [4] = {0xef,0xdf,0xbf,0x7f}; // 4X4由输出端子控制
//无符号字符KeyOut [4] = {0x7f,0xbf,0xdf,0xef};
无符号字符KeyOut [4] = {0x3f,0x5f,0x6f,0x77}; //两个端口组合的4x4端口输出控制
未签名的字符PortCom; //两个端口组合的端口
无符号字符cIn0,cIn1,cIn2,cIn3;
/ ************************************************** **************************************
**函数名称:无效延迟(无符号int毫秒)名称:无效延迟(无符号int毫秒)
**功能描述:可能已延迟
**输入参数:unsigned int ms输入近似延迟值
**输出:无
*************************************************** ************************************ /
无效延迟(无符号int ms)
{
无符号整数x,y;
for(x = ms; x》 0; x-)
for(y = 1000; y》 0; y-);
}
/ *
**说明:新的4X4按钮扫描程序用于1ms-10ms的中断(非常稳定,无需编写反跳程序)
**注意:当按钮弹出时,keyVal = 0单按keyVal有16个值,您自己的程序可以定位不同的值
**对于不同的程序操作,keyVal单键值分别为
** 0x01、0x02、0x04、0x08,
** 0x11、0x12、0x14、0x18,
** 0x21、0x22、0x24、0x28,
** 0x31、0x32、0x34、0x38,
* /
void Key_Head()
{
unsigned char ReadData [4];
静态无符号字符i;
/ *
PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
PD6 PD5 PD4 PD3 PD2 PA3 PA2 PA1
* /
cIn0 = 0;
cIn1 = 0;
cIn2 = 0;
cIn3 = 0;
if(++ i》 = 4) i = 0;
// PortCom = KeyOut [i] | 0x0f; //忽略低4位
//输出扫描

PD_ODR = KeyOut [i];
//输入检测
cIn0 = PA_IDR_bit.IDR1;
cIn1 = PA_IDR_bit.IDR2;
cIn2 = PA_IDR_bit.IDR3;
cIn3 = PD_IDR_bit.IDR2;
PortCom =(cIn3《《 [3) |(cIn2》《 2) |(cIn1《《 [1)》 | cIn0;
ReadData [i] =(PortCom | 0xf 0) ^ 0xff; //忽略高4位并反转
CF [i] = ReadData [i]&(ReadData [i] ^ Cont [i]);
Cont [i] = ReadData [i];
//输出键值
switch(CF [i])//第i列
{
case 0x08:KeyVal =((i《《《 4) + 8); break;
情况0x04:KeyVal =((i《《《 4) + 4); break;
case 0x02:KeyVal =((i《《《 4) + 2); break;
case 0x01:KeyVal =((i《《《 4) + 1); break;
default:KeyVal = 0; break;
}
delay(3 0);
}
/ ************************************************** **************************************
**函数名称:void ALL_LED_Init()名称:void ALL_LED_Init()
**功能描述:初始化LED灯的IO端口作为输出
**输入参数:无
**输出:无
*************************************************** ************************************ /
void ALL_LED_Init()
{
// LED1初始化
// PD_DDR_bit.DDR2 = 1; //将端口PD-》 2的输入输出方向寄存器设置为输出方向
// PD_CR1_bit.C12 = 1; //将PD2设置为推挽输出
// PD_CR2_bit.C22 = 1; //将PD2的最大输出速度设置为10MHZ
// LED2初始化
PC_DDR_bit.DDR7 = 1; //将端口PC-》 7的输入输出方向寄存器设置为输出方向
PC_CR1_bit.C17 = 1; //将PC7设置为推挽输出
PC_CR2_bit.C27 = 1; //将PC7的最大输出速度设置为10MHZ
// LED3初始化
PC_DDR_bit.DDR6 = 1; //将端口PC-》 6的输入输出方向寄存器设置为输出方向
PC_CR1_bit.C16 = 1; //将PC6设置为推挽输出
PC_CR2_bit.C26 = 1; //将PC6的最大输出速度设置为10MHZ
// LED4初始化
PC_DDR_bit.DDR3 = 1; //将端口PC-》 3的输入输出方向寄存器设置为输出方向
PC_CR1_bit.C13 = 1; //将PC3设置为推挽输出
PC_CR2_bit.C23 = 1; //将PC3的最大输出速度设置为10MHZ
}
/ ************************************************** **************************************
**函数名称:ALLKeyInit()
**功能说明:配置Key1,Key2,Key3输入按钮
**输入参数:无
**输出:无
*************************************************** ************************************ /
void ALLKeyInit()
{
// PA1_Init
PA_DDR_bit.DDR1 = 0; // GPA-》 PIN3设置为输入模式
PA_CR1_bit.C11 = 1; // GPA-》带上拉电阻输入的PIN3
PA_CR2_bit.C21 = 0; // GPA-》 PIN3禁止外部中断
// PA2_Init
PA_DDR_bit.DDR2 = 0; // GPA-》 PIN3设置为输入模式
PA_CR1_bit.C12 = 1; // GPA-》带上拉电阻输入的PIN3
PA_CR2_bit.C22 = 0; // GPA-》 PIN3禁止外部中断
// PA3_Init
PA_DDR_bit.DDR3 = 0; // GPA-》 PIN3设置为输入模式
PA_CR1_bit.C13 = 1; // GPA-》带上拉电阻输入的PIN3
PA_CR2_bit.C23 = 0; // GPA-》 PIN3禁止外部中断
// PD2_Init
PD_DDR_bit.DDR2 = 0; // GPD-》 PIN3设置为输入模式
PD_CR1_bit.C12 = 1; // GPD-》带上拉电阻输入的PIN3
PD_CR2_bit.C22 = 0; // GPD-》 PIN3禁止外部中断
// PD3_Init
PD_DDR_bit.DDR3 = 1; // GPD-》 PIN3设置为输入模式
PD_CR1_bit.C13 = 1; // GPD-》带上拉电阻输入的PIN3
PD_CR2_bit.C23 = 1; // GPD-》 PIN3禁止外部中断
// PD4_Init
PD_DDR_bit.DDR4 = 1; // GPD-》 PIN3设置为输入模式
PD_CR1_bit.C14 = 1; // GPD-》带上拉电阻输入的PIN3
PD_CR2_bit.C24 = 1; // GPD-》 PIN3禁止外部中断
// PD5_Init
PD_DDR_bit.DDR5 = 1; // GPC-》 PIN5设置为输入模式
PD_CR1_bit.C15 = 1; // GPC-》带上拉电阻输入的PIN5
PD_CR2_bit.C25 = 1; // GPC-》 PIN5禁止外部中断
// PD6_Init
PD_DDR_bit.DDR6 = 1; // GPC-》 PIN5设置为输入模式
PD_CR1_bit.C16 = 1; // GPC-》带上拉电阻输入的PIN5
PD_CR2_bit.C26 = 1; // GPC-》 PIN5禁止外部中断
}
int main(void)
{
CLK_CKDIVR = 0x00; //内部时钟除以1
ALL_LED_Init(); //调用LED1初始化函数
ALLKeyInit(); //调用按钮初始化函数
while(1)
{
Key_Head();
开关(KeyVal)
{
情况0x01:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
休息;
}
情况0x02:
{
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x04:
{
PC_ODR ^ = 0x08; //独家或倒置的LED4使其开启和关闭
休息;
}
情况0x08:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x11:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
休息;
}
情况0x12:
{
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x14:
{
PC_ODR ^ = 0x08; //独家或倒置的LED4使其开启和关闭
休息;
}
情况0x18:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x21:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
休息;
}
情况0x22:
{
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x24:
{
PC_ODR ^ = 0x08; //独家或倒置的LED4使其开启和关闭
休息;
}
情况0x28:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x31:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
休息;
}
情况0x32:
{
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
情况0x34:
{
PC_ODR ^ = 0x08; //独家或倒置的LED4使其开启和关闭
休息;
}
情况0x38:
{
PC_ODR ^ = 0x80; //异或将LED2反转以使其打开和关闭
PC_ODR ^ = 0x40; //异或将LED3反转以使其打开和关闭
休息;
}
默认值:
{
KeyVal = 0;
休息;
}
}
}
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-370323-1.html
范围不定
太完美了