在单片机怎么实现单个按键调音量里面有没有方法可以不用按键释放实现按下按键直接加一,不需要等待释放后再加一。

博客访问: 1558709
博文数量: 368
博客积分: 10828
博客等级: 上将
技术积分: 4211
注册时间:
微机键盘以其稳定性好、使用方便、价格便宜等优点,可有效地应用在输入量大、要求复杂的仪器仪表中。现存的计算机键盘种类很多,但基本原理和接口规范是一样的。IBM-PC键盘的核心器件是Intel公司的单片机8049。单片机采用行列扫描方法来监测是否有键按下。若有键按下,则转换为相应的扫描码,通过串行通讯线将其传给计算机,由主机接收并处理成扩展键盘码。
1 标准键盘工作原理
1.1 通信接口
键盘与计算机通过一个五芯接口插座座(PC/2接口为六芯)相接,各引脚定义分别是电源(VCC)、地(GND)、串行时钟线SCK和串行数据线SIO,还有一根线未用。两种键盘接口的插座外形图及各线定义如图1所示。
1.2 通信协议
标准键盘与计算机采用双向通信方式,键盘可以发送数据给计算机,计算机也可以发送命令给键盘。计算机有最高优先权,可以在任何时候发命令给键盘。通信协议是标准的串行异步通信格式,1位起始位,8位数据位(LSB在先),1位奇校验位P,最后是1位停止位。数据格式如图2所示。
当SIO和SCK同时为高电平时,键盘可以发数据给计算机。SCK可以用作清除发送线。如果计算机将SCK拉为低电平,键盘将不发送数据,而是将要发送的数据放到发送缓冲区中,直到SCK变为高电平才开始发送数据。如果计算机将SIO拉低,则键盘在检测到这一变化时,将接收来自计算机的命令。
图3(a)给出了键盘发送一个字节的时序。键盘先将SIO拉低,通知计算机准备接收数据。键盘在SCK的上升沿后改变数据,在下降沿时数据有效,可以被计算机读取。发送数据的时钟信号由键盘产生。有的文献介绍键盘时钟频率的典型值为20~30kHz,但实际上键盘的传送速原则不全在这个范围内。笔者曾做过测试,其中一只键盘的野外频率是12.4kHz。
图3(b)给出了键盘接收一个字节的时序。为了避免在同一时刻发送数据,建议计算机先将SCK拉低大约60μs 以上,以此通知键盘不要发数据。然后计算机将SIO拉低,表明发送数据开始,并释放SCK,由键盘接管SCK并产生时钟信号。计算机在此时钟信号的同步下发送数据。键盘接收数据是从检测到SIO变低开始的,然后在SCK下降沿读起始位,并在SCK的每个下降沿读取后缓数据。键盘在接收完校验位后,如果在下一个时钟周期检测到SIO处于空闲态(高电平),便会接受新数据并进行处理。在此期间,键盘将把SIO置成低电平,直到接受数据完成。如果收到校验位后,键盘检测到SIO没有处于空闲态,它将继续发送时钟信号直到SIO空闲。
1.3 键盘扫描码
一个基本按键的扫描码由3个字节组成,1个字节的接通扫描码和2个字节的断开扫描码。其中第一与第三个字节相同,中间字节是断开标志F0H。例如B键的接通扫描码是32H,断开扫描码是F0H32H。B键被按下时,32H被发送出去,如果一直按住不放,则键盘将以按键重复率不停地发送32H,直到该释放放,才发出断开扫描码F0H 32H.扫描码与按键折位置有关,与该键的ASCII码并无对应关系。键盘上还有部分扩展键(功能键和控制键等),这些键的扫描码由5个字节组成。与基本键的扫描码相比,接通扫描码与断开扫描码前各多了一个固定值字节E0H。例如Home键的接通扫描码是E0H 70H,熠工扫描码是E0H F0H 70H。还有两个特殊键,PrintScreen键的接通扫描码是E0H 12H E0H 7CH;断开扫描码是E0H F0H 7CH E0H F0H12H,PauseBreak键的接通扫描码是E1H 14H 77H E1H F0H 14H F0H 77H,无断开扫描码。
1.4 通信命令字
除了键盘可以向计算机发送按键的扫描码外,计算机还可以向键盘发送预定的命令字来对键盘功能进行设定。
1.4.1 计算机发往键盘的命令
EDH:设置状态指示灯。该命令用来控制键盘上3个指示灯NumLock、ScrollLock、CapLock的亮灭。EDH发出后,键盘将回应计算机一个收以应答信号FAH,然后等待计算机发送下一个字节,该字节决定各指示灯的状态。
Bit0控制ScrollL
Bit1控制NumL
Bit2控制CapL
Bit3~Bit7必须为0,否则键盘认为该字节是无效命令,将返回FEH,要求重发。
EEH:回送响应。该命令用于辅助诊断,要求键盘收到EEH后也回送EEH予以响应。
F0H:设置扫描码。键盘收到该命令后,将回送收到信号FAH,并等待下一命令字节,该字节的值01~03将决定键盘使用三种扫描码中的哪一种。
上电复位时,键盘默认扫描码类型是02,本文所举的例子皆为此类型扫描码。不同类型的扫描码与不同类型的微机相匹配。01类型扫描码由两字节组成,分别为接通扫描码和断开扫描码;03类型扫描码只有一个字节,为接通扫描码。
F3H:设置键盘重复速率,计算机发送该命令后,键盘将加送收到信号FAH,然后等待计算机的第二个字节,该字节决定按键的重复速率。
F4H:键盘使能。计算机发该命令给键盘后,将清除键盘发送缓冲区,重新使键盘工作,并返回收到信号FAH。
F5H:禁止键盘。计算机发该命令给键盘后,将使键盘复位,并禁止键盘扫描。键盘将返回收到信号FAH。
FEH:重发命令。键盘收到此命令后,将会把上次发送的最后一个字节重新发送。
FFH:复位键盘。此命令将键盘复位。若复位成功,键盘回送收到信号FAH和复位完成信号AAH。
1.4.2 键盘发往计算机的命令
00H:出错或缓冲区已满。
AAH:电源自检通过。BAT(基本保证测试)完成。
EEH:回送响应。
FAH:响应信号。键盘每当收到计算机的命令后,都会发此响应信号。
FEH:重发命令。计算机收到此命令后,将会把上次发送的最后一个命令字节重新发送。
FFH:出错或缓冲区已满。
2 键盘与单片机的接口电路及程序
采用Atmel89C51单片机与标准键盘接口电路如图4所示。口线P1.0和P1.1分别连接SCK和SIO,单片机的口线是上拉输出形式,可以和键盘的通信线直接相连,由软件控制口线产生收发时序。
应用程序合作Franklin C51编写。在程序中,单片机要用查询方式检测数据线状态。如果数据线变为低电平,说明键盘即将有数据发出,则调用读键盘子程序receive_data读取一个字节数据;若要发命令字给键盘,单片机则调用子程序send_data来完成。
单片机读取来自键盘数据的子程序如下,该程序接收一个字节数据存放在变量from_kb中,并将该值返回到主程序,校验位放在全局位变量p_bit中。
sbit sio=P1^1; /*数据线*/
sbit sck=P1^0; /*时钟线*/
sbit ACC_7=ACC^7;
sbit ACC_0=ACC^0;
bit p_ /*检验位*/
char receive_data(void)
char from_ /*放接收到的数据*/
while(sck);
while(!sck); /*放弃起始位*/
for(i=0;i<8;i++) /*读取数据字节*/
{ while(sck); /*下降沿读取数据*/
from_kb>>=1;
from_kb=ACC;
while(!sck);
while(sck);
p_bit= /*读取校验位*/
while(!sck);
while(sck); /*略去读停止位*/
while(!(sck&sio)); /*等待时钟线与数据线都释放*/
return(from_kb);
下列程序是89C51单片机发送一个命令字节给键盘的子程序。要发送的命令字由程序传送,并存于变量to_kb中,该程序按照接口的时序通过口线将命令字节传送给键盘。
Void send_to_kb(char to_kb) using 1
p_bit=!P; /*对发送字节进行奇校验,校验结果放在p_bit中*/
sck=0; /*将时钟线拉低*/
for(i=0;i<60;i++); /*时钟线低电平保持60μs以上,以禁止键盘往外发数据*/
sio=0; /*通知键盘接受命令字节,同时也作为起始位*/
sck=1; /*释放时钟线,以在键盘发出的时钟信号同步下,发送命令字*/
for(i=0;i<8;i++) /*发送命令字节*/
{ while(sck);
while(!sck); /*上升沿发数据*/
sio=ACC_0;
to_kb>>=1;
while(sck);
while(!sck);
sio=p_ /*发送奇校验位*/
while(sck);
while(!sck);
sio=1; /*释放数据线*/
单片机的嵌入式应用中有些需要进行大量的文字输入、参数修改和数值设定等操作。通常的方法是在电路中设计键盘电路、键盘接口的按键程序,这不仅占用许多硬件资源,而且由于键扫描处理程序一般都很庞大,软件开销也很大。如果在仪器上预留一个标准键盘接口,改用微机键盘对仪器仪表进行操作,则不仅占用系统资源少,成本低廉,而且微机键盘的键资源特别丰富,也给操作带来极大方便。本方法在学校打铃微电脑定时控制器中被采用,使得时间调整和上百组打铃设置操作变得非常容易。
阅读(2208) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
请登录后评论。一种实用的单片机按键检测方式
我的图书馆
一种实用的单片机按键检测方式
《手把手教你学51单片机》第八课讲解按键相关内容的时候,介绍了一种状态检测扫描按键的办法,既可以检测按键,又可以有效消抖。但是部分同学以前没有接触过类似的思想和方式,所以可能接受起来有点难度,这里我再详细给讲解分析一下,如果教程第八课你已经彻底明白,那么这里可以不用再学习了,如果还模模糊糊,可以再巩固一下。1、独立按键常用的按键电路有两种形式,独立式按键和矩阵式按键,独立式按键比较简单,它们各自与独立的输入线相连接,如下图所示。4条输入KeyIn1、KeyIn2、KeyIn3、KeyIn4接到单片机的IO口上,当按键K1按下时,+5V通过电阻R1然后再通过按键K1最终进入GND形成一条通路,那么这条线路的全部电压都加到了R1这个电阻上,KeyIn1这个引脚就和GND等电位,是个低电平。当松开按键后,线路断开,就不会有电流通过,那么KeyIn1和+5V就应该是等电位,是一个高电平。我们就可以读取通过KeyIn1这个IO口的高低电平来判断是否有按键按下,独立按键的原理还是很简单的。2、矩阵按键在某一个系统设计中,如果需要使用很多的按键时,做成独立按键会大量占用IO口,因此我们引入了矩阵按键的设计方式,如下图所示,用了8个IO口实现了16个按键检测的电路。上图,一共有4组按键,我们只看其中一组,如下图所示。大家认真看一下,如果KeyOut1输出一个低电平,KeyOut1就相当于是GND,是否相当于4个独立按键呢。当然这时候KeyOut2、KeyOut3、KeyOut4都必须输出高电平,它们都输出高电平才能保证与它们相连的三路按键不会对这一路产生干扰,大家可以对照两张原理图分析一下。同理,可以将KeyOut1,KeyOut3,KeyOut4都拉高,把KeyOut2拉低,来读取KEY5到KEY8的值。关于按键扫描的具体程序部分,大家可以去参考教程,我这里只把一段摘出来给大家讲一下,部分同学对其中一条语句有所疑问。while (1){if (KEY4 != backup) //当前值与前次值不相等说明此时按键有动作{if (backup == 0) //如果前次值为0,则说明当前是由0变1,即按键弹起{cnt++; //按键次数+1if (cnt >= 10){ //只用1个数码管显示,所以加到10就清零重新开始cnt = 0;}P0 = LedChar[cnt]; //计数值显示到数码管上}backup = KEY4; //更新备份为当前值,以备进行下次比较}}大家注意程序中加粗的部分,这一句是在 if (KEY4 != backup) 这一句的循环范围内,因此只要按键发生任何变化,按键的备份值backup这个变量,都会随着更新一次。3、按键消抖按键抖动的产生原理和造成的影响,这里不再赘述。那么重点研究一下如何消抖。初学者通常采用的办法是用delay来延时的办法,这种是一种演示实验的办法,做实际开发是万万不能用的,因为CPU一直在delay里工作,不能做其他事情,是一种很低级的办法。下面介绍一种状态采集的办法,这种办法不是把消抖单独拿出来处理,而是读的过程中,通过连续读取多次来确认当前的按键状态。通过多次判断,那么就可以消除抖动带来的影响。这样讲有点绕,还是用例子。一般的按键持续时间在100ms以上,抖动的时间,都是在10ms之内发生。那好了,那我们就2ms读一次按键,连续读8次,那一共是16ms,大于10ms的抖动时间,小于按键持续时间100ms。如果这8次状态是 ,那么就认为当前状态是按键弹起状态。如果这8次状态是,那么就认为当前状态是按键按下状态。那如果这8次状态是1和0混合的状态,那就认为当前的状态既不是弹起,也不是按下,可能是在刚按下,可能是在抖动过程,也可能是在快抖动完毕,总之状态是不确定的,这个时候我们就不做判断,既不认为他是按下,也不认为他是弹起,如下图所示,一个按键从弹起到按下,再到弹起的过程。同学们注意,我们读的是连续8次状态,而并不是间隔8个状态读一次,个别同学混淆,举例说明,数字用十六进制。第一次:第二次:第三次:3456789A第四次:456789AB....................................任何一次判断,只有全1认为是弹起,全0认为是按下,否则则认为按键处于抖动区间,不做判断。程序方面我只写主程序部分,用定时器定时2ms,在中断内部进行按键当前状态读取和更新,keybuf用来存储连续8次的按键状态,然后判断出来,把最终我们认为是“弹起”还是“按下”这样的最终状态结果,赋值给KeySta。那这里某一个按键我们确认是“弹起”还是“按下”加上扫描和消抖判断一共需要16ms即可确认。while (1){if (KeySta != backup) //当前值与前次值不相等说明此时按键有动作{if (backup == 0) //如果前次值为0,则说明当前是弹起动作{cnt++; //按键次数+1if (cnt >= 10){ //只用1个数码管显示,所以加到10就清零重新开始cnt = 0;}P0 = LedChar[cnt]; //计数值显示到数码管上}backup = KeyS //更新备份为当前值,以备进行下次比较}}/* T0中断服务函数,用于按键状态的扫描并消抖 */void InterruptTimer0() interrupt 1{static unsigned char keybuf = 0xFF; //扫描缓冲区,保存一段时间内的扫描值TH0 = 0xF8; //重新加载初值TL0 = 0xCD;keybuf = (keybufif (keybuf == 0x00){KeySta = 0; //连续8次扫描值都为0,可认为按键已按下}else if (keybuf == 0xFF){KeySta = 1; //连续8次扫描值都为1,可认为按键已弹起}else{} //其它情况则说明按键状态尚未稳定,则不对KeySta变量值进行更新}这种状态扫描的办法是工程中常用的一个办法,介绍给大家使用。这里虽然判断一次按键也用了16ms,但是真正单片机在读按键状态的程序时间是很短的,我们不需要停留在一直等待按键状态发生变化的那个过程中,这个时候单片机可以做很多其他的事情。矩阵按键有16个,如果还是按照2ms采集一次,一次可以采集1组共4个按键的情况,一共采集8次的话,需要的总时间 = 2ms*8次*(16/4)= 64ms,这个时间就有点太长了。这里的时间计算方式,部分同学混淆,所以我把式子详细列了出来。那我们对矩阵按键的处理方式采取状态时间间隔减半,确认最终所需要的读取状态次数减半处理,时间间隔1ms读一次,每次可以读一组4个按键,每个按键需要采集4次最终确认按键是“弹起”还是“按下”,那读完了的总时间 = 1ms*4次*(16/4)=16ms。但是有一点这里重点强调(凡事这里重点强调的,就是有其他同学混淆的),每一个按键都是16ms才能确认按键状态,但是扫描时间一旦开启,是每间隔4ms,按键就判断到一次。第一次:1234第二次:2345第三次:3456第四次:4567----------------------#include sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;sbit KEY_IN_1 = P2^4;sbit KEY_IN_2 = P2^5;sbit KEY_IN_3 = P2^6;sbit KEY_IN_4 = P2^7;sbit KEY_OUT_1 = P2^3;sbit KEY_OUT_2 = P2^2;sbit KEY_OUT_3 = P2^1;sbit KEY_OUT_4 = P2^0;unsigned char code LedChar[] = { //数码管显示字符转换表0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};unsigned char KeySta[4][4] = { //全部矩阵按键的当前状态{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};void main(){unsigned char i,unsigned char backup[4][4] = { //按键值备份,保存前一次的值{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};EA = 1; //使能总中断ENLED = 0; //选择数码管DS1进行显示ADDR3 = 1;ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;TMOD = 0x01; //设置T0为模式1TH0 = 0xFC; //为T0赋初值0xFC67,定时1msTL0 = 0x67;ET0 = 1; //使能T0中断TR0 = 1; //启动T0P0 = LedChar[0]; //默认显示0while (1){for (i=0; i{for (j=0; j{if (backup[i][j] != KeySta[i][j]) //检测按键动作{if (backup[i][j] != 0) //按键按下时执行动作{P0 = LedChar[i*4+j]; //将编号显示到数码管}backup[i][j] = KeySta[i][j]; //更新前一次的备份值}}}}}/* T0中断服务函数,扫描矩阵按键状态并消抖 */void InterruptTimer0() interrupt 1{static unsigned char keyout = 0; //矩阵按键扫描输出索引static unsigned char keybuf[4][4] = { //矩阵按键扫描缓冲区{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}};TH0 = 0xFC; //重新加载初值TL0 = 0x67;//将一行的4个按键值移入缓冲区keybuf[keyout][0] = (keybuf[keyout][0] keybuf[keyout][1] = (keybuf[keyout][1] keybuf[keyout][2] = (keybuf[keyout][2] keybuf[keyout][3] = (keybuf[keyout][3] //消抖后更新按键状态for (i=0; i{if ((keybuf[keyout][i] & 0x0F) == 0x00){ //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下KeySta[keyout][i] = 0;}else if ((keybuf[keyout][i] & 0x0F) == 0x0F){ //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起KeySta[keyout][i] = 1;}}//执行下一次的扫描输出keyout++; //输出索引递增keyout = keyout & 0x03; //索引值加到4即归零switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚{case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0;case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0;case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0;case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0;default:}}4、长短按键在单片机系统中应用按键的时候,如果想连续加很多数字的时候,我们会希望一直按住按键,数字就自动持续增加或减小,这就是所谓的长短按键应用。当检测到一个按键产生按下动作后,马上执行一次相应的操作,同时在程序里记录按键按下的持续时间,该时间超过1秒后(主要是为了区别短按和长按这两个动作,因短按的时间通常都达到几百ms),每隔200ms(如果你需要更快那就用更短的时间,反之亦然)就自动再执行一次该按键对应的操作,这就是一个典型的长按键效果。程序代码摘自《手把手教你学51单片机》教程第十课,详细代码有想了解的可以去看,这里只把和长短按键有关系的部分代码摘录出来。void KeyDriver(){unsigned char i,static unsigned char pdata backup[4][4] = { //按键值备份,保存前一次的值{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};static unsigned long pdata TimeThr[4][4] = { //快速输入执行的时间阈值{, }, {, },{, }, {, }};for (i=0; i{for (j=0; j{if (backup[i][j] != KeySta[i][j]) //检测按键动作{if (backup[i][j] != 0) //按键按下时执行动作{KeyAction(KeyCodeMap[i][j]); //调用按键动作函数}backup[i][j] = KeySta[i][j]; //刷新前一次的备份值}if (KeyDownTime[i][j] > 0) //检测执行快速输入{if (KeyDownTime[i][j] >= TimeThr[i][j]){ //达到阈值时执行一次动作KeyAction(KeyCodeMap[i][j]); //调用按键动作函数TimeThr[i][j] += 200; //时间阈值增加200ms,以准备下次执行}}else //按键弹起时复位阈值时间{TimeThr[i][j] = 1000; //恢复1s的初始阈值时间}}}}void KeyScan(){static unsigned char keyout = 0; //矩阵按键扫描输出索引static unsigned char keybuf[4][4] = { //矩阵按键扫描缓冲区{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}};//将一行的4个按键值移入缓冲区keybuf[keyout][0] = (keybuf[keyout][0] keybuf[keyout][1] = (keybuf[keyout][1] keybuf[keyout][2] = (keybuf[keyout][2] keybuf[keyout][3] = (keybuf[keyout][3] //消抖后更新按键状态for (i=0; i{if ((keybuf[keyout][i] & 0x0F) == 0x00){ //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下KeySta[keyout][i] = 0;KeyDownTime[keyout][i] += 4; //按下的持续时间累加}else if ((keybuf[keyout][i] & 0x0F) == 0x0F){ //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起KeySta[keyout][i] = 1;KeyDownTime[keyout][i] = 0; //按下的持续时间清零}}//执行下一次的扫描输出keyout++; //输出索引递增keyout &= 0x03; //索引值加到4即归零switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚{case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0;case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0;case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0;case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0;default:}}不管你以后遇到的是什么样的按键,这种扫描按键状态的思路,提供你参考学习,以后再也不要在实际工程中用delay函数来消抖了,那样会让领导一看你就是新手,用的方法很low,自然给你定薪水待遇的时候,印象分就会低。如果你写出这种实用的实际开发的程序给领导一看,领导很可能对你另眼相看。
推一荐:&&|&&
喜欢该文的人也喜欢21ic官方微信-->
单片机定时5秒长按按键有效进入执行程序否则不足5秒或者没有按键则执行另一程序
资深技术员, 积分 361, 距离下一级还需 139 积分
资深技术员, 积分 361, 距离下一级还需 139 积分
资深技术员, 积分 361, 距离下一级还需 139 积分
资深技术员, 积分 361, 距离下一级还需 139 积分
单片机最好是NXP1778其他也可以,我参考一下定时5秒长按按键有效进入执行程序否则不足5秒或者没有按键则执行另一程序,提供点思路或者代码,谢谢了
满意回复+10
这就是个按键,状态机的功能,可百度搜索马老师按键状态 方法
先对按键计时,然后通过if判断来跳转到不同的程序段
用状态机吧,按键扫描放在定时器中断中,按键按下返回一个标志,按键到达5s钟返回一个标志,再结合按键释放后的标志判断即可。 ...
高级技术员, 积分 651, 距离下一级还需 349 积分
高级技术员, 积分 651, 距离下一级还需 349 积分
高级技术员, 积分 651, 距离下一级还需 349 积分
高级技术员, 积分 651, 距离下一级还需 349 积分
这就是个按键,状态机的功能,可百度搜索马老师按键状态 方法&&
高级技术员, 积分 606, 距离下一级还需 394 积分
高级技术员, 积分 606, 距离下一级还需 394 积分
高级技术员, 积分 606, 距离下一级还需 394 积分
高级技术员, 积分 606, 距离下一级还需 394 积分
楼上正解,可以参考论坛的大佬 程序匠人的按键漫谈,里面有详细的讲解按键的各种 短按、长按、双击等
先对按键计时,然后通过if判断来跳转到不同的程序段
资深技术员, 积分 326, 距离下一级还需 174 积分
资深技术员, 积分 326, 距离下一级还需 174 积分
资深技术员, 积分 326, 距离下一级还需 174 积分
资深技术员, 积分 326, 距离下一级还需 174 积分
5秒精确的计时,定时器外部捕捉。或者定时中断里检查
用状态机吧,按键扫描放在定时器中断中,按键按下返回一个标志,按键到达5s钟返回一个标志,再结合按键释放后的标志判断即可。
推荐先看看坛子里菜农的零耗时按键。
扫描二维码,随时随地手机跟帖
技术新星奖章
人才类勋章
时间类勋章
技术奇才奖章
人才类勋章
涓涓之细流
发帖类勋章
时间类勋章
终身成就奖章
等级类勋章
坚毅之洋流
发帖类勋章
时间类勋章
技术领袖奖章
人才类勋章
核心会员奖章
等级类勋章
技术导师奖章
人才类勋章
您需要登录后才可以回帖
热门推荐 /5【单片机按键判断长按】 - CSDN使用51单片机如何实现多个按键输入,采用中断方式,若无按键按下时MCU做其它工作。C程式编写。_百度知道
使用51单片机如何实现多个按键输入,采用中断方式,若无按键按下时MCU做其它工作。C程式编写。
本人是初学单片机,请教使用51单片机如何实现多个按键输入(2个以上,即使用普通IO口实现中断),程式如何采用中断方式实现,若无按键按下时MCU做其它工作。若有现成的C程式十分感谢,...
本人是初学单片机,请教使用51单片机如何实现多个按键输入(2个以上,即使用普通IO口实现中断),程式如何采用中断方式实现,若无按键按下时MCU做其它工作。若有现成的C程式十分感谢,程式最好相细一点,否则看不懂呀。谢谢!
&#xe6b9;答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
采纳数:13302
获赞数:34836
多个按键输入(2个以上,即使用普通IO口实现中断),程式如何采用中断方式实现,...--------51单片机,有两个外部中断输入端,它们也算是普通IO口。外部中断,应该用于处理一些突发事件,需要单片机紧急处理的事件。按键,不能算是需要紧急处理的事件。对普通按键进行处理,还需要延时消抖,等待按键释放等环节,时间上,没有紧迫的要求。用外部中断,来处理按键,就是自寻烦恼。可以到我的 百度空间 看看,里面有很多用普通IO口连接按键的处理方法。
华仔880102
华仔880102
获赞数:36
当按键按第一次时间,进入第一层循环查询语句内部,执行恢复。不跳出该层循环,继续查询按键。当第二次按下时间,进入第二层循环查询语句内部,执行暂停。循环结束。若想反复暂停和恢复,就在外面再加一层while(1)类似的死循环,反复执行其内部的两层循环查询语句。 2.用一个标志变量,记住按键的状态。初始化为个值,如“暂停”,按键之后检查标志变量,是“暂停”就执行“恢复”,再让它变为“恢复”说明当前已经执行了恢复。反之亦然。 3.掉电暂停。这样需要按键能触发cpu工作。所以,需要按键接到外部中断上面。中断后可以恢复CPU工作。在中断中再判断是否要让cpu掉电与否。 不知道这种方法你能接受不?还是用外部中断。此按键触发中断后,关掉所有其他的中断,也即EA=0(最好先用个变量记住EA,方便恢复),然后就一直在中断中等待该按键第二次按下再恢复EA,最后退出中断。
是否可以舉例說明,謝謝!
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 单片机怎么实现单个按键调音量 的文章

 

随机推荐