51单片机单按键多击程序遇到问题
本帖最后由 daiya1981 于 2020-7-6 08:31 编辑写了一个响应单按键多击的程序,按键弹起大于0.5S后返回键值,有问题,无法运行。可是我才疏学浅,找不到问题出在哪里。请各位高人帮忙看看问题出在哪?
#include <reg52.h>
sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit KEY1 = P3^2;
unsigned int count = 0,ClickFlagCount = 0;
unsigned char i = 0,ClickFlag = 0,keynum = 0;
unsigned char keyscan(void)
{
if(KEY1)
{
if(count > 30 && count < 3000)
{
ClickFlag = 1;
keynum++;
}
count = 0;
if(ClickFlag == 1)
{
if(ClickFlagCount++ > 500)
{
ClickFlag = 0;
return keynum;
keynum = 0;
}
else
{
ClickFlag = 0;
}
}
else
{
ClickFlagCount = 0;
}
}
else
{
count++;
if(count > 3000)
count = 3001;
}
return 0;
}
void main()
{
EA = 1; //使能总中断
TMOD = 0x01;//设置T0为模式1
TH0= 0xFC;//为T0赋初值0xFC67,定时1ms
TL0= 0x67;
ET0= 1; //使能T0中断
TR0= 1; //启动T0
while (1)
{
switch (i)
{
case 1:
LED0 = ~LED0;
break;
case 2:
LED1 = ~LED1;
break;
case 3:
LED2 = ~LED2;
break;
default:
break;
}
}
/* 定时器0中断服务函数 */
void InterruptTimer0() interrupt 1
{
TH0 = 0xFC;//重新加载初值
TL0 = 0x67;
i = keyscan();
} 有什么问题不说清楚一点,看下定时器中断函数能进去不。 本帖最后由 daiya1981 于 2020-7-6 08:28 编辑
定时器中断函数肯定进得去,我测试过了。这个程序是响应单按键多击,只要在按键抬起0,5秒之内按下均有效,可以响应1~N击,是个通用程序,可是由于我水平限制,里面肯定有错误,自己找不出来,请大家帮忙 我添加了注释,不知道可不可以看清楚逻辑了?
unsigned char keyscan(void)
{
if(KEY1)
{
if(count > 30 && count < 3000) //如果按下时间30ms~3s,认为是单击
{
ClickFlag = 1; //按键抬起标志置1
keynum++; //键号加1
}
count = 0; // 键按下时间计数器清0
if(ClickFlag == 1) //如果按键抬起标志为1
{
if(ClickFlagCount++ > 500) //按键抬起时间大于0.5s
{
ClickFlag = 0; //按键抬起标志清0
return keynum; //返回键号
keynum = 0; //键号清0
}
else //按键抬起时间小于0.5s
{
ClickFlag = 0;
}
}
else //如果按键抬起标志为0
{
ClickFlagCount = 0; //清0按键抬起时间计数器
}
}
else
{
count++; //按键按下时间计数器加1
if(count > 3000) //防止数据溢出
count = 3001;
}
return 0;
} 打赏!
庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏
https://www.amobbs.com/thread-5735948-1-1.html 我们一般将键盘设计成一个独立模块,产生单击、延时击、延时后的快击,几种状态码,然后到相应的任务模块里调看键值,简单可靠。尽量不用定时器去延时,只用主程序执行的周期做计时,对于按键的去抖延时20-40毫秒,均无防。这样可以减少定时器的支出。
给你一段代码:
#include "Use.h"
#include "Ver.H"
#define Timer20ms (80/TK_MAIN) //ÑÓʱʱ¼ä20mS
#define Timer3S (1500/TK_MAIN) //ÑÓʱʱ¼ä2S
#define Timer100ms (200/TK_MAIN) //ÑÓʱʱ¼ä100mS
//**********************************************************
KEY KeyDat; //¶¨ÒåÊý¾Ý½á¹¹
//**********************************************************
sbit KeyIn=P1^6;
sbit Clk_Key595=P2^7;
sbit Rck_Key595=P0^2;
sbit Dat_Key595=P0^3; //
//*********************************************
void SenDat_Key595(unsigned char Dat){
unsigned char j=8;
Rck_Key595=0;
for (j=0;j<8;j++){
Clk_Key595=0;
Dat_Key595=(bit)(Dat & 0x80);
Clk_Key595=1;
Dat<<=1; //×óÒÆÊäÈë
}
Rck_Key595=1;
}
//*********************************************
unsigned char ReadKey(void){
unsigned char i,j=0;
j =~HMLCtrl;
j &=0x0f;
j<<=1;
if (fBZ==0) j |=0x01;
//*****************************************
i =0x60 | j; // 0111,1111=7f 2005-3-22
KeyIn=1;
SenDat_Key595(i);
if (!KeyIn) return 1; //Ka
i=0xa0 | j; //1011,1111 =bf
SenDat_Key595(i);
if (!KeyIn) return 2; //kb
i=0xc0 | j; //1101,1111=df
SenDat_Key595(i);
if (!KeyIn) return 3; //kc
//***************************** KFo KFs
return 0;
}
/************************************
ÅбðÊÇ·ñÓмü
*************************************/
void GetKey (void){
if (ReadKey()!=0) {
KeyDat.KeyDog=Timer20ms;
KeyDat.KeyPower++;
}
}
/**************************************
ÑÓʱȥ¶¶¶¯
***************************************/
void KeyDog(void){
if (--KeyDat.KeyDog== 0){
KeyDat.KeyData=ReadKey(); //¶Á¼üÅÌ
if (KeyDat.KeyData!=0){
KeyDat.KeyPower++;
KeyDat.KeyDog=Timer3S;
}else{
KeyDat.KeyPower=0;
KeyDat.KeyData=0; //·µ»Ø
}
}
}
/*********************************
ÅбðÊÇ·ñËÉ¿ª
**********************************/
void KeyOff1(void){
unsigned char i;
i=ReadKey();
if (i==0){ //ËÉ¿ª°´¼ü
KeyDat.KeyPower=0;
KeyDat.KeyData |=HaveKey; //¶¨Òå±êÖ¾
//*****************************************
Beep_Start(0); //·äÃùÆ÷¶ÌÃù
//******************************************
}else{
if (--KeyDat.KeyDog == 0){ //3ÃëÑÓʱµ½
//*****************************************
Beep_Start(0);//·äÃùÆ÷¶ÌÃù
//******************************************
KeyDat.KeyData |=HaveKey | DubClick; //3SºóËÉ¿ªµÃµ½³¤ÑÓʱ¼ä¶¨Òå±êÖ¾
KeyDat.KeyDog=3*Timer100ms;
KeyDat.KeyPower++;
}
}
}
/**********************************
Á¬»÷ÊÇ·ñËÉ¿ª
**********************************/
void KeyOff2(void){
unsigned char i;
i=ReadKey();
if (i!=0){
if (--KeyDat.KeyDog == 0){
KeyDat.KeyData =i | HaveKey | AddClick; //¼ÓËÙ»÷±êÖ¾
KeyDat.KeyDog=Timer100ms;
//*****************************************
Beep_Start(0);//·äÃùÆ÷¶ÌÃù
//******************************************
}
}else{
KeyDat.KeyData =0;
KeyDat.KeyPower =0;
}
}
/**********************************
º¯ÊýÖ¸Õ붨Òå
***********************************/
code void (code *SubKey[])()={
GetKey,KeyDog,KeyOff1,KeyOff2
};
/*****************************
¼ü´¦Àí³ÌÐò
******************************/
void KeyBord(void){
(*SubKey)();
}
/**************************************
¼ü´¦ÀíºóÇå³ý¼üÖµ
***************************************/
unsigned char JB_KeyData(void){
unsigned char i=0;
if (KeyDat.KeyData > DubClick){
i=KeyDat.KeyData;
KeyDat.KeyData=0;
}
return i;
}
奇怪了中文变成乱码。 /*****************************************************
¼üÅ̵ļüÖµ¶¨Òå
******************************************************/
#define AddClick 0x20 //Á¬»÷
#define DubClick 0x40 //µ¥»÷
#define HaveKey 0x80 //Óмü
#define Ka (0x01|HaveKey)
#define Kb (0x02|HaveKey)
#define Kc (0x03|HaveKey)
#define Ko (0x04|HaveKey)
#define Ks (0x05|HaveKey)
#define Kos (0x06|HaveKey)
#define Ka_Dub (Ka| DubClick | HaveKey) //Ë«»÷
#define Kb_Dub (Kb| DubClick | HaveKey)
#define Kc_Dub (Kc| DubClick | HaveKey)
#define Ko_Dub (Ko | DubClick | HaveKey)
#define Ks_Dub (Ks| DubClick | HaveKey)
#define Kos_Dub (Kos | DubClick | HaveKey)
#define Ka_Add (Ka| HaveKey | AddClick) // ¼ÓËÙ
#define Kb_Add (Kb| HaveKey | AddClick)
#define Kc_Add (Kc| HaveKey | AddClick)
#define Ko_Add (Ko | HaveKey | AddClick)
#define Ks_Add (Ks| HaveKey | AddClick)
#define Kos_Add (Kos | HaveKey | AddClick)
//*******************************************************************
//ºìÍâ¼üÅ̶¨Òå
//*******************************************************************
#define K0_IR 0
#define K1_IR 1
#define K2_IR 2
#define K3_IR 3
#define K4_IR 4
#define K5_IR 5
#define K6_IR 6
#define K7_IR 7
#define K8_IR 8
#define K9_IR 9
//*********************************************************************
#define Ka_IR 1
#define Kb_IR 1
#define Kc_IR 1
#define Kd_IR 1
#define Ke_IR 1
#define Kf_IR 1
//*********************************************************************
#define K_up_IR 1
#define K_down_IR 1
#define K_left_IR 1
#define K_right_IR 1
#define K_ok_IR 1
#define K_esc_IR 1
//---------------------------------------
typedef struct{
unsigned char KeyPower; //ÃüÁî×Ö
unsigned intKeyDog; //ÑÓʱ
unsigned char KeyData; //¼üÖµ
}KEY; 采用状态机,将键译程序分解成几个工作状态。 学习了,谢谢
页:
[1]