C51单片机矩阵键盘扫描去抖程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C51单片机矩阵键盘扫描去抖程序

最近有一个C51的项目,用的是新华龙的C51 F020单片机。项目中要实现4*5的矩阵键盘。矩阵电路图如下如示

其中,四条列线接在F020的P2~P5口线上,5条行线接在P5口线上(F020的P5口是不同于普通C51的扩展接口,不能位寻址)。同时4条列线接在一四输入与非门(74LS20)上,门输出接F020的外中断1,这样,任何一键按下,都会产生中断,通知程序进行键盘扫描。

托一个新手给写了键盘的扫描程序,基本功能都能实现,但对于键盘的去抖处理总是做不好,表现是或者不能去抖,或者按键响应过慢,或者采集到错误键值。看来新手对于矩阵键盘扫描原理掌握较好(网上资料多),但对于键盘去抖的知识却有所欠缺,基本都是按照书上说的延时一段时间再采集键值,实际应用中,这样的处理是远远不够的,过于简单。实际去抖处理应该这样进行更合理一些,即连续采集键值,当采集到的键值在一段时间内是相同的,即认为按键状态已稳定,此键值为真实键值。另外,按键释放时,也会有抖动,导致误采键值,因此在键释放时,也应进行去抖处理,处理方法同时是连续一段时间采集到无键按下状态,才认为按键被释放。根据这个方法,我重写了新手的程序,实际应用中表现极好。

现将程序公布如下,供新手参考。

Key.h文件内容

#ifndef __key_H__

#define __key_H__

#define NULL_KEY 0x0000

#define S1 0x3801

#define S2 0x3401

#define S3 0x3802

#define S4 0x3402

#define S5 0x3804

#define S6 0x3404

#define S7 0x3808

#define S8 0x3408

#define S9 0x3810

#define S10 0x3410

#define S11 0x2C01

#define S12 0x1C01

#define S13 0x2C02

#define S14 0x1C02

#define S15 0x2C04

#define S16 0x1C04

#define S17 0x2C08

#define S18 0x1C08

#define S19 0x2C10

#define S20 0x1C10

#define KEY_DELAY 20

extern unsigned int Key_Value;

extern void Init_Key();

extern void Scan_Key();

extern bit Key_Pressed;

extern bit Key_Released;

extern unsigned int idata Keypress_Count;

extern unsigned int idata Keyrelease_Count;

#endif

key.c 文件内容

#include

#include "key.h"

bit Key_Down; //是否有键按下的标志unsigned int idata Keypress_Count;

sbit Col_Key0 = P2^2;

sbit Col_Key1 = P2^3;

sbit Col_Key2 = P2^4;

sbit Col_Key3 = P2^5;

bit Key_Pressed;

bit Key_Released;

unsigned int Key_Value;

bit Key_Down; //是否有键按下的标志unsigned int idata Keypress_Count; //一毫秒增加一次的变量unsigned int idata Keyrelease_Count; //一毫秒增加一次的变量//矩阵键盘使用中断1作为键盘中断

void Init_Key()

{

P5 = 0; //行线全部置为0

EX1 = 1; // 允许外部时钟秒中断

IT1 = 1; // 外部时钟中断设置为边沿触发}

void Key_Int() interrupt 2

{

Key_Pressed = 1;

EX1 = 0;

}

void Scan_Key()

{

unsigned char temp,rowvalue;

unsigned int key;

int i;

temp = P2;

temp &= 0x3C;

if(temp == 0x3C)

{

Key_Released = 0;

Key_Pressed = 0;

key = NULL_KEY;

EX1 = 1;

}

else

{

key = temp;

key = key<<8;

rowvalue = 0x01;

for(i=0;i<5;i++)

{

P5 = rowvalue<

DelayMs(1);

temp = P2;

temp &= 0x3C;

if(temp == 0x3c)

{

rowvalue = rowvalue<

key = key | rowvalue;

P5 = 0x00;

break;

}

}

P5 = 0x00;

DelayMs(1);

}

if(key!=NULL_KEY) //如果有键按下

{

if(key==Key_Value) //如果按下的是相同的键{

if(Keypress_Count>=KEY_DELAY)

{

Key_Down = 1;

}

}

else if(Key_Down != 1)

{

Keypress_Count=0;

Keyrelease_Count = 0;

Key_Value=key;

}

}

else //如果无键按下

{

相关文档
最新文档