51单片机独立按键程序松手时的判断程序出了问题但是不知道在哪里

51单片机独立按键程序松手时的判断程序出了问题但是不知道在哪里,第1张

#include<reg51h>

#include<intrinsh>

#define K1 P0^0

#define uchar unsigned char

#define uint unsigned int

delay(uint,uint); //这里的分号吧

void main()

{

P2=0x01;

while(1)

{

if(K1==0)

{

delay(100,100);

P2=_cror_(P2,1) ; //

if(K1!=0) //

delay(100,100); //

}

}

}

delay(uint x,uint y)

{

uint i,j;

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

for(j=0;j<y;j++);

}

在这里加一个while语句的目的是防抖动,也就是说防止你按一下键,由于抖动的原因,而单片机响应好几下。比如你的按键接在p00上,sbit

ds=p00

当你按下的时候ds=0,放手的时候又是1,所以应该是while(ds==0);这句话就是在等待你松手,你松手以后才继续执行命令

/

矩阵按键实验

实现现象:下载程序后数码管显示0,按下矩阵按键上的按键显示对应的数字

S1-S4:0-3

S5-S8:4-7

S9-S12:8-B

S13-S16:C-F。

注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。

/

#include "reg52h" //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16; //对数据类型进行声明定义

typedef unsigned char u8;

#define GPIO_DIG P0

#define GPIO_KEY P1

sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;

u8 KeyValue; //用来存放读取到的键值

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

/

函 数 名 : delay

函数功能 : 延时函数,i=1时,大约延时10us

/

void delay(u16 i)

{

while(i--);

}

/

函 数 名 : KeyDown

函数功能 : 检测有按键按下并读取键值

输 入 : 无

输 出 : 无

/

void KeyDown(void)

{

char a=0;

GPIO_KEY=0x0f;

if(GPIO_KEY!=0x0f)//读取按键是否按下

{

delay(1000);//延时10ms进行消抖

if(GPIO_KEY!=0x0f)//再次检测键盘是否按下

{

//测试列

GPIO_KEY=0X0F;

switch(GPIO_KEY)

{

case(0X07): KeyValue=0;break;

case(0X0b): KeyValue=1;break;

case(0X0d): KeyValue=2;break;

case(0X0e): KeyValue=3;break;

}

//测试行

GPIO_KEY=0XF0;

switch(GPIO_KEY)

{

case(0X70): KeyValue=KeyValue;break;

case(0Xb0): KeyValue=KeyValue+4;break;

case(0Xd0): KeyValue=KeyValue+8;break;

case(0Xe0): KeyValue=KeyValue+12;break;

}

while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测

{

delay(1000);

a++;

}

}

}

}

/

函 数 名 : main

函数功能 : 主函数

输 入 : 无

输 出 : 无

/

void main()

{

LSA=0; //给一个数码管提供位选

LSB=0;

LSC=0;

while(1)

{

KeyDown(); //按键判断函数

GPIO_DIG=smgduan[KeyValue]; //

}

}

//假设按键上拉

if(key == 0)

{

delay_ms(20) ; //防抖动

while(key == 0) //常按等待

{

key = key_scan() ; //获得按键值

}

}

这是独立键盘的 *** 作方法,矩阵键盘和这个原理是一样的,你改一下就好了。

检测到按键被按下后,在消抖延时的过程中反复检测,若延时过程中按键松开(或d开),则退出,直到再次检测到按键被按下

并且,关键是,消抖延时最好利用定时中断来做,这样的话,在消抖的过程中,也不会影响其它的工作

我的一般做法是,将定时器设定为1mS中断一次,假如你采用15mS做按键消抖,那就在按键检测程序中检测到按键被按下时,设一个标志位,然后1mS之内就会进定时中断,在中断中判断按键是否继续被按下,若是,则对一个寄存器加一,若不是,则清除按键的标志位和该寄存器若寄存器计到15了,就表示该按键已经持续了15个mS是有效的,可以判断为一次有效按键了

这样做的好处在于,由于在中断中只是判断和设定一两个标志位,因此占用的中断时间很少很少,剩余的时间就可以退出中断去继续干别的

并且,这个1mS的定时时间,还可以作为系统中其它功能的一个"时基",也可以理解成软件的"节拍",对这个1mS进行计数,可以得到任何想要的定时标志,例如10mS、100mS、1S等等,这对于很多软件来说,比单纯的一个大循环要好调配得多,并且还容易找出有冲突的地方,便于维护和升级

当然,对于不同速度的芯片来说,定时器1mS的定时周期或许不太合适,那也可以改为2mS或5mS,反正是便于计数和计算的一个基础值就可以

希望对你有用^_^

--------

按一次会连续加几次的问题,是因为你没有对按键的"松开"进行判断

也就是说,按键按下后,执行过一次了,就设定一个标志位,直到该按键被松开,才清除这个标志位这样的话,当再次执行到该按键的时候,就可以判断这一次按键有没有执行过,也就是,这一次按键"有没有用过"用过了就跳过,没用过才用

以上就是关于51单片机独立按键程序松手时的判断程序出了问题但是不知道在哪里全部的内容,包括:51单片机独立按键程序松手时的判断程序出了问题但是不知道在哪里、我想问一个关于c51单片机单键识别松手检测的问题、求助程序:51单片机矩阵键盘是否按下检测程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10631769.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存