矩阵键盘(4*4)扫描
一、 IO口赋值后,读取 IO 口状态时,需要延时处理。否则会检测不到,IO 口状态。(之前,在STC15上面使用正常,这次调试突然STC8 使用时,出现问题。猜测是 STC8 上的个别问题)
程序一共 3 处 延时。
- 按键 消抖
- 读取 IO 口 前,延时处理
- 读取 IO 口 前,延时处理
二、用法
void main()
{
static uchar key_value=0;
/* 串口初始化 */
UART1_T2_authority_init();
printf("Uart1_T2_init!\r\n");
/* 矩阵键盘初始化 */
Key_int();
printf("Key_init !\r\n");
while(1)
{
key_value=Key_Down_scan();
printf("key=%bd\r\n",key_value); //输出一次数据
Key_clear_value(); //处理按键事件后,清除按键 -- 键值
Delay500ms();
}
}
三、程序`
1.matrix_keyboard_hxd.h
/*
* 版权声明: 暂无
* 文件名称 : matrix_keyboard_hxd.h
* 创建者 : 黄星达
* 创建日期: 2018/9/20
* 文件描述: 4*4 矩阵键盘
* 历史记录: 无
* 功能 :矩阵键盘扫描
* 增加功能:无
* 最后修改日期: 2018/9/21
*/
#ifndef matrix_keyboard_hxd_h
#define matrix_keyboard_hxd_h
#include <Type.h>
#include <STC8.h>
#include "intrins.h"
#include <GPIO_Mode_Set.h>
/*************矩阵键盘******************/
#define GPIO_KEY P6 //键盘引脚
#define GPIO_KEY_PIN1 60
#define GPIO_KEY_PIN2 61
#define GPIO_KEY_PIN3 62
#define GPIO_KEY_PIN4 63
#define GPIO_KEY_PIN5 64
#define GPIO_KEY_PIN6 65
#define GPIO_KEY_PIN7 66
#define GPIO_KEY_PIN8 67
static uchar KeyValue = 0; // 矩阵键盘--按键值 1-16 0为没有检测到按键动作
static void Delay10us(int16 value); // 软件延时 单位10us
void Key_int(void); //矩阵键盘初始化
uchar Key_Down_scan(void); //矩阵键盘扫描
void Key_clear_value(void); //处理按键事件后,清除按键 -- 键值
#endif
2.matrix_keyboard_hxd.C
/*
* 版权声明: 暂无
* 文件名称 : matrix_keyboard_hxd.h
* 创建者 : 黄星达
* 创建日期: 2018/9/20
* 文件描述: 4*4 矩阵键盘
* 历史记录: 无
* 功能 :4*4 矩阵键盘扫描
* 增加功能:无
* 最后修改日期: 2018/9/21
*/
/*
* 使用方法:1.在 matrix_keyboard_hxd.h 设置矩阵键盘 IO 口
* 2.程序初始化 调用 Key_int(); //矩阵键盘初始化
* 3.定时器中断中调用 Value= KeyDown(); //扫描键盘 并 返回最后一次按键的按键值 1-16 。不会清0,需要手动 置0
*
*/
#include "matrix_keyboard_hxd.h"
#include <UART.h>
#include <stdio.h>
/*******************************************************************************
* 函数名 : Key_int
* 函数功能 : 矩阵键盘初始化
* 输入 : 无
* 输出 : 无
* 作者 : HXD
* 日期地点 : 泉州 -----------2018-9-21
*******************************************************************************/
void Key_int(void) //矩阵键盘初始化
{
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN1,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN2,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN3,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN4,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN5,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN6,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN7,GPIO_MODE_QSBD);
Set_GPIO_Pxx_Mode(GPIO_KEY_PIN8,GPIO_MODE_QSBD);
GPIO_KEY=0;
}
/*******************************************************************************
* 函数名 : KeyDown_scan
* 函数功能 : 检测有按键按下并读取键值
* 输入 : 无
* 输出 : KeyValue 按键值 返回最后一次按键的按键值 1-16 。不会清0,需要手动 置0
* 作者 : INK
* 日期地点 : NANKING
*******************************************************************************/
uchar Key_Down_scan(void)
{
GPIO_KEY=0xF0; // 位定义的引脚
if(GPIO_KEY!=0x0F) //读取按键是否按下
{
// printf("key_down",GPIO_KEY); //输出一次数据
Delay10us(1); //延时10ms进行消抖
if(GPIO_KEY!=0x0F) //再次检测键盘是否按下
{
// printf("key_down",GPIO_KEY); //输出一次数据
//测试列
GPIO_KEY=0X0F;
Delay10us(1); //延时10ms后读取 IO 口状态。
GPIO_KEY=0X0F&GPIO_KEY;
switch(GPIO_KEY)
{
//此段程序只是为了确定列的值 方便在后面进行测试行的时候加减运算 获得具体案件的行列值 从而转换为按键值
case(0X07):
{
{
KeyValue=1;
}
break;//扫描第一列
}
case(0X0b):
{
{
KeyValue=2;
}
break;//按键第二列
}
case(0X0d):
{
{
KeyValue=3;
}
break;//按键第三列
}
case(0X0e):
{
{
KeyValue=4;
}
break;//按键第四列
}
default:break; //P1=0XF0;
}
// printf("KeyValue=%bd ",KeyValue); //输出一次数据
//测试行 确定了列以后需要翻转 确定行 交叉确定键值
GPIO_KEY=0XF0; //屏蔽高四位
Delay10us(1); //延时10ms进行消抖
GPIO_KEY=0XF0&GPIO_KEY;
P7=GPIO_KEY;
switch(GPIO_KEY)
{ //已经进行过
case(0X70):
{
{
KeyValue=KeyValue;
}
break; //自己去看为什么是 0X70 列的时候又为什么是0X07 硬件相结合
}
case(0XB0):
{
{
KeyValue=KeyValue+4;
}
break; //键值是 扫描第二行
}
case(0XD0):
{
{
KeyValue=KeyValue+8;
}
break; //键值是 扫描第三行
}
case(0XE0):
{
{
KeyValue=KeyValue+12;
}
break; //键值 扫描第四行
}
default:break;
}
// printf("KeyValue=%bd ",KeyValue); //输出一次数据
//其实最终返回的键值就是进行过加法运算的
// while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测 松手 按键就是 f0
// {
// Delay10us(10);
// a++;//防止程序死在 while循环里 利用a的值跳出循环,比较不错的双重保险办法
// }
}
}
return KeyValue;
}
/*******************************************************************************
* 函数名 : Delay10us
* 函数功能 : 软件延时,单位10us
* 输入 : value 延时系数
* 输出 : 无
* 作者 : HXD
* 日期地点 : 2018/5/31 --------------------------------------------- 泉州
*******************************************************************************/
static void Delay10us(int16 value) //@30.000MHz
{
unsigned char i;
for(;value>0;value--)
{
_nop_();
_nop_();
i = 72;
while (--i);
}
}
/*******************************************************************************
* 函数名 : Key_clear_value
* 函数功能 : 处理按键事件后,清除按键 -- 键值
* 输入 : 无
* 输出 : 无
* 作者 : HXD
* 日期地点 : 泉州 -----------2018-10-9
*******************************************************************************/
void Key_clear_value(void)
{
KeyValue=0;
}