c语言按键消抖常用方法

合集下载

按键消除抖动的措施

按键消除抖动的措施

按键消除抖动的措施
按键消除抖动是指在使用电子设备中,当按下按键后可能会出
现的多次触发信号的问题。

为了解决这个问题,可以采取以下措施:
1. 软件滤波,在程序设计中,可以采用软件滤波的方法来消除
按键抖动。

软件滤波可以通过延时、状态机等方式来确保只有真正
的按键按下才会触发相应的操作,而忽略短暂的抖动信号。

2. 硬件滤波,在电路设计中,可以加入电容、电阻等元件来实
现硬件滤波,通过延长按键信号的上升沿或下降沿时间,从而消除
按键抖动带来的干扰。

3. 使用稳定的按键元件,选择质量好、稳定性高的按键元件,
可以减少按键抖动的发生。

4. 金属片设计,在按键设计中,可以添加金属片来增加按键的
稳定性,减少抖动。

5. 硬件消抖器,使用专门的硬件消抖器芯片,这些芯片可以自
动检测和消除按键抖动,提高按键的稳定性。

综上所述,消除按键抖动可以通过软件滤波、硬件滤波、选择稳定的按键元件、金属片设计以及使用硬件消抖器等多种措施来实现。

在实际应用中,可以根据具体情况选择合适的方法或者结合多种方法来解决按键抖动问题。

单片机原理及应用课后习题答案第5章作业

单片机原理及应用课后习题答案第5章作业

第五章中断系统作业1. 外部中断1所对应的中断入口地址为()H。

2. 对中断进行查询时,查询的中断标志位共有、_ _、、_ 和_ 、_ _ 六个中断标志位。

3.在MCS-51中,需要外加电路实现中断撤除的是:()(A) 定时中断(B) 脉冲方式的外部中断(C) 外部串行中断(D) 电平方式的外部中断4.下列说法正确的是:()(A) 同一级别的中断请求按时间的先后顺序顺序响应。

()(B) 同一时间同一级别的多中断请求,将形成阻塞,系统无法响应。

()(C) 低优先级中断请求不能中断高优先级中断请求,但是高优先级中断请求能中断低优先级中断请求。

()(D) 同级中断不能嵌套。

()5.在一般情况下8051单片机允许同级中断嵌套。

()6.各中断源对应的中断服务程序的入口地址是否能任意设定? ()7.89C51单片机五个中断源中优先级是高的是外部中断0,优先级是低的是串行口中断。

()8.各中断源发出的中断申请信号,都会标记在MCS-51系统中的()中。

(A)TMOD (B)TCON/SCON (C)IE (D)IP9. 要使MCS-51能够响应定时器T1中断、串行接口中断,它的中断允许寄存器IE的内容应是()(A)98H (B)84H (C)42 (D)22H10.编写出外部中断1为负跳沿触发的中断初始化程序。

11.什么是中断?其主要功能是什么?12. 什么是中断源?MCS-51有哪些中断源?各有什么特点?13. 什么是中断嵌套?14.中断服务子程序与普通子程序有哪些相同和不同之处?15. 中断请求撤除的有哪三种方式?16. 特殊功能寄存器TCON有哪三大作用?17. 把教材的P82页的图4.24改为中断实现,用负跳变方式,中断0(INT0)显示“L2”,中断1(INT1)显示“H3”。

(可参考第四章的电子教案中的例子)18.第5章课后作业第9题。

第五章中断系统作业答案1. 外部中断1所对应的中断入口地址为(0013)H。

按键消抖

按键消抖

一、按键消抖1.1 计数器型消抖电路(一)计数器型消抖电路(一)是设置一个模值为(N+1)的控制计数器,clk在上升沿时,如果按键开关key_in='1',计数器加1,key_in='0' 时,计数器清零。

当计数器值为2时,key_out 输出才为1,其他值为0时。

计数器值为N时处于保持状态。

因此按键key_in持续时间大于N个clk时钟周期时,计数器输出一个单脉冲,否则没有脉冲输出。

如果按键开关抖动产生的毛刺宽度小于N个时钟周期,因而毛刺作用不可能使计数器有输出,防抖动目的得以实现。

clk的时钟周期与N的值可以根据按键抖动时间由设计者自行设定。

主要程序结构如下:图1是N为3的波形仿真图,当按键持续时间大于3个时钟周期,计数器输出一个单脉冲,其宽度为1个时钟周期,小于3个时钟周期的窄脉冲用作模拟抖动干扰,从图1可以看出,抖动不能干扰正常的单脉冲输出。

1 按键抖动产生原因分析绝大多数按键都是机械式开关结构,由于机械式开关的核心部件为弹性金属簧片,因而在开关切换的瞬间会在接触点出现来回弹跳的现象。

虽然只是进行了一次按键,结果在按键信号稳定的前后出现了多个脉冲,如图1所示。

如果将这样的信号直接送给微处理器扫描采集的话,将可能把按键稳定前后出现的脉冲信号当作按键信号,这就出现人为的一次按键但微处理器以为多次按键现象。

为了确保按键识别的准确性,在按键信号抖动的情况下不能进入状态输入,为此就必须对按键进行消抖处理,消除抖动时不稳定、随机的电压信号。

机械式按键的抖动次数、抖动时间、抖动波形都是随机的。

不同类型的按键其最长抖动时间也有差别,抖动时间的长短和按键的机械特性有关,一般为5~10 ms,但是,有些按键的抖动时间可达到20 ms,甚至更长。

所以,在具体设计中要具体分析,根据实际情况来调整设计。

2 按键消抖电路的设计按键消抖一般采用硬件和软件消抖两种方法。

硬件消抖是利用电路滤波的原理实现,软件消抖是通过按键延时来实现。

单片机原理与应用课后习题答案

单片机原理与应用课后习题答案

课后思考题级习题答案思考题与习题1一、填空通用型 和 专用型 。

微控制器 和 单片微型计算机 。

二、简答1.什么是单片机?答:单片机也称微控制器,它是将中央处理器、程序处理器、数据处理器、输入/输出接口、定时/计数器串行口、系统总线等集成在一个半导体芯片上的微计算机,因此又称为单片微型计算机,简称为单片机。

2.简述单片机的特点和应用领域。

答:〔1〕单片机体积小,应用系统结构简单,能满足很多应用领域对硬件功能的要求。

〔2〕单片机的可靠性高。

〔3〕单片机的指令系统简单,易学易用。

〔4〕单片机的开展迅速,特别是最近几年,单片机的部结构越来越完善。

3.写出AT89S51与AT89S52芯片的主要区别。

部程序存储区容量不同,52的程序存储空间为8K ,部数据存储空间为256B ,中断源8个,定时器/计数器有3个,而51的程序存储空间为4K ,部数据存储空间为128B ,中断源5个,定时器/计数器有2个。

思考题与习题2一、填空题1.如果〔PSW 〕=10H, 如此部RAM 工作存放器区的当前存放器是第二 组存放器,8个存放器的单元地址为 10H ~ 17H 。

2.为寻址程序状态字F0位,可使用的地址和符号有 PSW.5 、 0D0H.5 、 F0 和 0D5H 。

3.单片机复位后,〔SP 〕= 07H ,P0~P3= FFH ,PC= 0000H ,PSW= 00H A= 00H 。

PC 决定的,由于AT89S51单片机的PC 是 16 位的,所以最大寻址围为 64KB 。

5.写出位地址为20H 所在的位,字节地址 24H.0 。

07H ,最低位的位地址为 00H 。

MHz 6OSC f ,如此一个时钟周期为,一个机器周期为2us 。

8. AT89S51单片机共有26个特殊功能存放器。

9. AT89S51单片机片外数据存储器最多可以扩展64KB 。

10.如果CPU 从片外ROM 的0000H 单元开始执行程序,那么EA 引脚应接 低电平。

按键处理程序C语言单片机

按键处理程序C语言单片机

按键处理程序C语言单片机分享一种按键处理程序(用C)//头文件定义:Ustruct KEY{Uchar Val;#define Key_Model_C 0 //按键1值#define Key_AddVal_C 1 //按键2值Uint ScanOnTime;Uchar LongKeyState;Uchar LongKeyRestState;Uchar SetInRn;Uchar Model; //按键状态(模式)#define Off_C 0 //之前未按下#define On_C 1 //现按下#define Delay_C 2 //按键处理后标志}Key;//----------------定义两个IO输入口为按键入口--------------------//#define KeyMo_Bin (GPIOB->IDR.Bit.B5)#define KeyAdd_Bin (GPIOB->IDR.Bit.B6)/*===================================== ==========================*/GPIO_Init(GPIO_Pin_5|GPIO_Pin_6,GPIO_Mode_In_PU_No_IT); //初始化为上拉输入无中断/*===================================== ==========================*///主程序大循环中每1毫秒扫描1次void KeyScan(void){if(Key.LongKeyRestState == 1) //长按键标志(复位处理长按键){if((KeyMo_Bin == 1) && (KeyAdd_Bin == 1)) //当两按键均抬起{if(++Key.ScanOnTime >= 130) //延时后复位{Key.LongKeyRestState=0;Key.Model=Delay_C;}}elseKey.ScanOnTime=0;return;}if(Key.Model == Off_C) //如果当前按键状态为未按下“Off_C”{if((KeyMo_Bin == 0) || (KeyAdd_Bin == 0))//按键1或按键2已按下(低有效){if(++Key.ScanOnTime >= 10) //当按下后自加1,加够10次即1ms*10=10ms去抖动{Key.ScanOnTime=0;if(KeyMo_Bin == 0) //如果按键1为0即按下{Key.Val=Key_Model_C; //付当键1值(看头文件定义)Key.Model=On_C; //置按键已按下标志}else if(KeyAdd_Bin == 0) //如果按键2为0即按下{Key.Val=Key_AddVal_C; //付当键2值(看头文件定义)Key.Model=On_C; //置按键已按下标志}BellOn(200); //蜂鸣器响}}elseKey.ScanOnTime=0; //清去抖延时计数值}else if(Key.Model == Delay_C) //如果当前按键状态为已按下且已处理“Delay_C”{if((KeyMo_Bin == 1) && (KeyAdd_Bin == 1))//如果两按键均抬起{if(++Key.ScanOnTime >= 100) //延时100ms后复位按键状态为“Off_C”{Key.SetInRn=0;Key.ScanOnTime=0;Key.Model=Off_C;}}else //如果按键没有被抬起,对应上面if{if(++Key.ScanOnTime >= 1000) //延时1000ms后再复位按键状态为“Off_C”(为长按处理){Key.ScanOnTime=0;Key.Model=Off_C;}}}}//===================================== ========================================= ========void LoadCheckKeyRest(void){Key.LongKeyRestState=1;Key.ScanOnTime=0;}//===================================== ========================================= ========//处理相应按键(可250ms才调用一次)长按if(Key.Model == On_C) //按键状态为已按下{if(Key.Val == Key_Model_C) //是键1按下(看头文件定义){if(++Key.SetInRn >= 3) //连计3次数3秒后为长按键(对应上面,如果按下未抬起的话会延时1000ms){Key.SetInRn=0;LoadCheckKeyRest(); //调清长按处理BellOn(600); //蜂鸣器响//-----------长按需处理的内容-----下-----------//WorkStateBit.Bit.SettingMo=1;SetOverTime=0;SetMoRn=0;SetBak[0]=Rtc_InitDate.RTC_Year;SetBak[1]=Rtc_InitDate.RTC_Month;SetBak[2]=Rtc_InitDate.RTC_Date;SetBak[3]=Rtc_InitDate.RTC_WeekDay;SetBak[4]=Rtc_InitTime.RTC_Hours;SetBak[5]=Rtc_InitTime.RTC_Minutes;//-----------长按需处理的内容------上----------//Key.Model=Delay_C; //置按键模式为:已处理按键(看头文件定义)return;}}elseKey.SetInRn=0;Key.Model=Delay_C;}。

51C语言源代码

51C语言源代码

闪烁灯[实验要求]点亮与单片机P1.0口相连的发光二极管,延时0.2S,然后熄灭,延时0.2S,再点亮,如此循环下去。

[实验目的]初步了解单片机IO口输出高低电平的作用,延时函数的时间估算。

[硬件电路][源代码]#include<reg51.h>/**********************************************************上面这行是一个"文件包含"处理。

所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来这里的程序虽然只写了一行,但C编译器在处理的时候却要处理几十或几百行,这里包含reg51.h的目的在于本程序要使用P1这个符号,而P1是在reg51.h这个头文件中定义的。

大家可以在编译器目录下面用记事本打开这个文件看看。

*********************************************************/sbit P1_0=P1^0; //定义IO口这步的目的是让编//译器知道P1_0代表的就是单片机的P1.0口void delay02s(void) //延时0.2秒子程序{unsigned char i,j,k; //定义3个无符号字符型变量。

for(i=20;i>0;i--) //三个FOR循环用来延时,这里为for(j=20;j>0;j--) //什么是0.2S大家可以用WAVE for(k=248;k>0;k--); //高断点仿真一下,就可知道大概 } //是0.2S了。

void main(void) //每一个C语言程序有且只有一个主函数,{while(1) //循环条件永远为真,以下程序一直执行下去。

{P1_0=0; // I/O口P1.0输出低电平,小灯被点亮。

delay02s(); //延时经过0.2秒。

P1_0=1; // I/O口P1.0输出高电平,小灯熄灭。

键盘消抖原理代码说明(Verilog)

笔记2 键盘消抖(别人的笔记)老实说,这个实验的开始之前和之后,都给我蛋疼了。

时钟了解不到源码的思路,边看源码边睡着。

醒来的时候既然“惊”一下,相通了......module lesson02(CLK, RST,SW0, SW1, SW2,LED0, LED1, LED2);input CLK;input RST;input SW0, SW1, SW2;output LED0, LED1, LED2;//---------------------------------------------------------------------------//Detect the switch pressingreg [2:0] Press0;reg [2:0] Press1;wire [2:0] isPress;always @ (posedge CLK or negedge RST)if(!RST)Press0 <= 3'b111;elsePress0 <= {SW0, SW1, SW2}; //read the pin result;always @ (posedge CLK or negedge RST)if(!RST)Press1 <= 3'b111;elsePress1 <= Press0; //read the previous Press0 resultassign isPress=Press1 & (~Press0); //detect the logic with bit is changed from logic 1 to 0 //---------------------------------------------------------------------------//if pressing, counter start counting for 20msreg [19:0] Counter; //计数寄存器always @ (posedge CLK or negedge RST)if(!RST)Counter <= 20'd0;else if(isPress)Counter <= 20'd0;elseCounter <= Counter + 1'b1; //increment for counter//------------------------------------------------------------------------//After 20ms read the key pin resultreg [2:0] Press2;reg [2:0] Press3;wire [2:0] Result;always @ (posedge CLK or negedge RST)if(!RST)beginPress2 <= 3'b111;Press3 <= 3'b111;endelse if(Counter == 20'hfffff)Press2 <= {SW0, SW1, SW2}; //read the pin result after 20mselsealways @ (posedge CLK or negedge RST)if(!RST)elsePress3 <= Press2; //read the previous pin resultassign Result = Press3 & (~Press2); //detect the changing bit from logic 1 to 0//------------------------------------------------------------------------//turn on led with pin resultreg D1;reg D2;reg D3;always @ (posedge CLK or negedge RST)if(!RST)beginD1 <= 1'b0;D2 <= 1'b0;D3 <= 1'b0;endelsebeginif( Result[0] ) D1 <= ~D1;if( Result[1] ) D2 <= ~D2;if( Result[2] ) D3 <= ~D3;endassign LED0 = D1 ? 1'b1 : 1'b0;assign LED1 = D2 ? 1'b1 : 1'b0;assign LED2 = D3 ? 1'b1 : 1'b0;endmodule这个实验主要有计数器和边缘检查来实现按键消抖,按键功能。

按键消抖

状态机实现去抖动原理:按键去抖动关键在弄提取键稳定的电平状态,滤除前沿、后沿抖动毛刺。

对于一个按键信号,可以用一个脉冲对它进行取样,如果连续三次取样为低电平,可以认为信号已经处于键稳定状态,这时输出一个低电平的按键信号。

继续取样的过程如果不能满足连续三次取样为低,则认为键稳定状态结束,这时输出变为高电平。

设计的状态转换图如图所示。

Reset信号有效时,电路进入复位状态s0,这时认为取样没有检测到低电平,在输入取样过程中,每次检测到一个低电平,发生依次向下的状态转移,直到连续检测到三个低电平时,进s3态,这时输出置低(按键信号稳定态),在中间状态s1,s2时,一旦检测到高电平,就进入s0状态,重新检测。

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity xiaod isport(clk : in std_logic ;reset : in std_logic ;din : in std_logic ;dout : out std_logic);end entity;architecture rtl of xiaod isTYPE state IS( s0,s1,s2,s3);SIGNAL pre_s, next_s: state;beginprocess( reset, clk )beginif reset = '0' thenpre_s <= s0;elsif rising_edge( clk ) thenpre_s <= next_s;elsenull;end if;end process;process( pre_s, next_s, din ) begincase pre_s iswhen s0 =>dout <= '1';if din = '1' thennext_s <= s0;elsenext_s <= s1;end if;when s1 =>dout <= '1';if din = '1' thennext_s <= s0;elsenext_s <= s2;end if;when s2 =>dout <= '1';if din = '1' thennext_s <= s0;elsenext_s <= s3;end if;when s3 =>dout <= '0';if din = '1' thennext_s <= s0;elsenext_s <= s1;end if;end case;end process ;end rtl;程序中din为要去抖动的热键信号,dou为去抖后输出的稳定信号。

MCS-51单片机技术项目驱动教程C语言第二版牛军课后参考答案

MCS-51单片机技术项目驱动教程C语言第二版习题答案第1章思考与练习1. 什么是单片机?最早的单片机是什么时间推出的?答:单片机是单片微型计算机的简称,它将中央处理器(CPU)、随机存储器(RAM)、只读存储器(ROM)、中断系统、定时器/计数器、串行口和I/O接口等主要计算机部件集成在一块大规模集成电路芯片上,具有了微型计算机的组成结构和功能。

最早的单片机是在20世纪70年代初推出的。

2. 简述单片机的特点。

答:单片机具有种类众多、性价比高、集成度和可靠性高、存储器ROM和RAM严格区分、采用面向控制的指令系统、I/O引脚通常是多功能的、外部扩展能力强等特点。

3. 什么是MCS-51单片机?最早是哪家公司推出的?答:MCS-51单片机是所有兼容Intel 8051指令系统单片机的统称,最早由Intel 公司推出。

4. 说出4种以上常用的单片机类型。

答:(1)MCS-51单片机;(2)AVR单片机;(3)PIC单片机;(4)MSP430单片机;(5)Motorola单片机。

5. 什么是总线?单片机中的总线有哪几种?答:总线是指从任意一个源点到任意一个终点的一组传输数字信息的公共通道。

单片机中总线包括地址总线、数据总线和控制总线三种。

6. 简述单片机中位和字节的概念。

答:一个二进制数叫1位,相邻的8位二进制数构成一个字节。

7.存储地址的作用是什么?答:存储地址用来定义每个存储单元,以供CPU寻址、操作。

第2章思考与练习1. AT89C51单片机的内部ROM 和RAM分别是多大空间?最多可扩展多少空间?答:分别是4KB和128B,ROM最多可扩展60KB,RAM最多可扩展64KB。

2. AT89C51单片机有哪几个中断源?答:有3个内部中断源和2个外部中断源。

3. 画出MCS-51单片机的复位电路原理图,包括上电复位和手动复位功能,并根据参数计算上电复位时高电平的持续时间。

答:复位电路原理图如下图所示。

单片机按键去抖原理

单片机按键去抖原理在单片机系统中,按键的应用非常广泛,无论是控制还是交互,经常需要使用按键来进行操作。

然而,由于按键的特性,往往会带来按键抖动的现象,这就需要对按键进行去抖处理。

本文将详细介绍单片机按键去抖的原理和方法。

1.按键抖动的原因及影响因素按键抖动是指按下或释放按键时,按键触点会产生不稳定的接触,导致按键信号在短时间内多次切换,造成系统误判。

按键抖动的原因主要有以下几点:(1)按键机械结构问题:按键存在接触不良、触点弹簧不稳定等机械问题,会导致接触突变。

(2)外部干扰:如按键线路附近的磁场、电源干扰等,会引发按键误触。

(3)按键的弹性和灵敏度:按键材料和设计的不同,会导致按键的弹性和灵敏度不一致,进而引发抖动。

按键抖动会带来以下几个问题:(1)误判:按键抖动会使系统误判按键的按下或释放,导致错误的逻辑操作。

(2)数据错误:抖动会造成按键信号的短时间内多次切换,可能导致数据传输错误、丢失等问题。

(3)系统性能下降:由于抖动会产生大量的开关信号,会占用系统资源,影响系统的运行速度和响应时间。

2.去抖的原理去抖的原理是通过软件或硬件的方式对按键信号进行滤波,消除了按键抖动信号,从而得到稳定的按键信号。

软件去抖的原理是通过软件算法对按键信号进行处理,主要有两种方法:软件延时去抖和状态机去抖。

(1)软件延时去抖:软件延时去抖的原理是在按键按下后,通过添加延时来屏蔽抖动信号。

当检测到按键按下后,先延时一段时间,并再次检测按键的状态,如果按键仍然处于按下状态,则确认按键按下有效。

软件延时去抖的优点是简单易行,只需通过软件延时来实现,无需额外的硬件支持。

缺点是实现的延时时间需要适当,过短容易漏掉有效按键,过长则会增加系统响应时间。

(2)状态机去抖:状态机去抖的原理是通过状态变化来屏蔽抖动信号。

状态机的设计是基于按键的状态转换,当按键按下时,状态变为按下状态;当按键释放时,状态变为释放状态。

只有在状态转换时,才认定按键按下或释放为有效信号。

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

在C语言中,按键消抖是指处理物理按键在按下或释放时可能产生的抖动或不稳定信号的问题。

常用的方法包括软件延时消抖和状态机消抖。

1. 软件延时消抖:
- 当检测到按键按下或释放时,可以通过在代码中添加一个短暂的延时来过滤掉按键可能产生的抖动信号。

例如,在按键检测到变化后,延时几毫秒以确保按键信号稳定后再进行状态读取。

```c
void delay(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 300; j++);
}
// 在按键检测中使用延时
if (button_pressed && !last_button_state) {
delay(10); // 等待10毫秒
if (button_pressed) {
// 执行按键按下后的操作
last_button_state = button_pressed;
}
}
```
这种方法简单易行,但需要根据具体硬件和按键特性调整延时时间,且可能会造成按键响应速度变慢。

2. 状态机消抖:
- 利用状态机来跟踪按键状态变化,并在一定持续时间内保持一致的状态才认定为有效按键按下或释放。

这可以通过一个状态变量和定时器结合实现。

```c
enum ButtonState {IDLE, PRESSED, RELEASED};
enum ButtonState current_state = IDLE;
unsigned int debounce_timer = 0;
// 在按键检测中使用状态机
void button_check() {
switch (current_state) {
case IDLE:
if (button_pressed) {
current_state = PRESSED;
debounce_timer = 10; // 设定10毫秒的延时
}
break;
case PRESSED:
if (!button_pressed) {
current_state = RELEASED;
debounce_timer = 10; // 设定10毫秒的延时
}
break;
case RELEASED:
if (button_pressed) {
current_state = PRESSED;
debounce_timer = 10; // 设定10毫秒的延时
}
break;
}
if (debounce_timer > 0) {
debounce_timer--;
} else {
if (current_state == PRESSED) {
// 执行按键按下后的操作
} else if (current_state == RELEASED) {
// 执行按键释放后的操作
}
current_state = IDLE; // 处理完毕后返回IDLE状态 }
}
```
这种方法相对于延时消抖更加灵活,可以根据具体需求设置不同的延时时间,并且不会影响整体的按键响应速度。

以上是在C语言中常用的按键消抖方法,根据具体的硬件和项目需求选择合适的方法来处理按键的抖动问题。

相关文档
最新文档