此片文章用于记录蓝桥杯单片机的学习
篮球杯单片机上的矩阵按键原理图如下:
使用矩阵键盘时,要将跳线帽J5跳至KBD模式。
值得注意的是,若开发板上的单片机使用的为STC15,那么以上原理图适用。如果单片机为IAP15,则在上述原理图中,要将P36换成P42,P37换成P44。
修改如下(IAP15):
常用的矩阵键盘扫描方式有行扫描法和线反转法,在比赛过程中,为了提高键盘的扫描速度和程序的运行效率,这里建议采用三步消抖法加线反转法,这样程序运行效率较高,并且支持按键的短按和长按。
线反转法原理简单,配合三步消抖即可支持按键的快速扫描和长按与短按。
矩阵键盘程序如下:
KET4X4.c(IAP15)
#include <STC15F2K60S2.H>
#define u8 unsigned char
#define KEY_4X4 //定义KEY_4X4就代表使用矩阵按键模式
#ifdef KEY_4X4
u8 Key_4_value; //用来记录键值
bit Key_time_falg; //用来做为计时标志位
unsigned long Key_time; //用来记录按键按下的时间,进而判断是长按还是短按
u8 Key_scan4x4() {
u8 Key_temp, Key_value;
P3 = 0x0f;
P42 = 0;
P44 = 0;
Key_temp = (P3 & 0x0f);
switch (Key_temp) {
case (0x07): Key_value = 4; break; //第四行按下 0000 0111
case (0x0b): Key_value = 5; break; //第三行按下 0000 1011
case (0x0d): Key_value = 6; break; //第二行按下 0000 1101
case (0x0e): Key_value = 7; break; //第一行按下 0000 1110
default: Key_value = 0; break;
}
P3 = 0xf0; //1111 0000
P42 = 1;
P44 = 1;
Key_temp = (P3 & 0xf0);
if (P44 == 0) { //第一列按下
Key_value = Key_value;
} else if (P42 == 0) { //第二列按下
Key_value = Key_value + 4;
} else if (Key_temp == 0xd0) { //第三列按下
Key_value = Key_value + 8;
} else if (Key_temp == 0xe0) { //第四列按下
Key_value = Key_value + 12;
}
return Key_value;
}
void Read_key4x4() {
u8 Key_up, Key_down, Key_temp;
static u8 Key_old = 0;
Key_temp = Key_scan4x4();
Key_down = Key_temp & (Key_old ^ Key_temp); //三步消抖法,Key_donw是按键按下的键值 Key_up是按键弹上的键值 Key_old用来记录上一次的键值
Key_up = ~Key_temp & (Key_old ^ Key_temp);
Key_old = Key_temp;
if (Key_down) //如果需要在按键按下就立马执行 则可以在这里对把Key_donw的值给Key_4_value
{
Key_time_falg = 1; //开始计时
}
if (Key_up) //这里是按键按下 并松手了才执行
{
Key_time_falg = 0; // 已松手 结束计时
if (Key_time >= 500) // 如果按下的时间大于500,则为长按 否则为短按
{
Key_4_value = Key_up + 100;
Key_time = 0;
} else {
Key_4_value = Key_up;
Key_time = 0;
}
}
}
#endif
KET4X4.h
#ifndef _KEY4X4_H_
#define _KET4X4_H_
#define u8 unsigned char
u8 Key_scan4x4();
void Read_key4x4();
#endif
现在,在主程序中配置好定时器和中断即可:
Main.c
#include <STC15F2K60S2.H>
#include "intrins.h"
// #include "74LS138.h"
// #include "Key4.h"
#include "KEY4X4.h"
extern u8 Key_4_value; //记录键值
extern unsigned long Key_time; //记录按下的时间
extern bit Key_time_falg; //计时标志位
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
EA = 1;
ET0 = 1;
TR0 = 1; //定时器0开始计时
}
void main() {
// init_ls138(); // 上电关闭所有外设
Timer0Init();
while (1) {
if (Key_4_value == 11) //按键S11被按下
{ /*做事情*/
} else if (Key_4_value == 10) //按键S10被按下
{ /*做事情*/
} else if (Key_4_value == 18) //按键S18被按下
{ /*做事情*/
} else if (Key_4_value == 19) //按键S19被按下
{ /*做事情*/
} else if (Key_4_value == 111) //按键S11被长按
{ /*做事情*/
} else if (Key_4_value == 110) //按键S10被长按
{ /*做事情*/
} else if (Key_4_value == 118) //按键S18被长按
{ /*做事情*/
} else if (Key_4_value == 119) //按键S19被长按
{ /*做事情*/
}
}
}
void Tim0_interrupt() interrupt 1 {
static u8 i = 0;
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
i++;
if (Key_time_falg == 1) {
Key_time++;
}
if (i >= 10) { //10ms按键扫描一次
Read_key4x4();
i = 0;
}
}
在程序中,只需要判断KEY-4-value的值即可分辨按键哪个被按下,分别对应S4~S19,长按的键值为原本的键值加上100。
蓝桥杯单片机学习日记1-LED 蜂鸣器 继电器 数码管的简单驱动文章来源:https://www.toymoban.com/news/detail-409910.html
蓝桥杯单片机学习日记2-独立按键的短按,长按的使用文章来源地址https://www.toymoban.com/news/detail-409910.html
到了这里,关于蓝桥杯单片机学习日记3-矩阵键盘的使用,线反转法,三步消抖,按键长按与短按的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!