数码管加减计数(按键消抖)
按键消抖计数原理与测试说明
“按键消抖计数”程序测试与原理说明1程序运行效果说明按下KEY1,数码管上的示数加1。
按下KEY2,数码管上的示数减1。
2程序电路工作原理以及按键抖动原因按键电路示意图(三个按键分别是K1、K2、K3)当按键被按下的时候,电路导通接地,I/O口为低电平;当按键未被下时,电路断开,I/O口保持高电平的。
但一般的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。
因而在闭合及断开的瞬间均伴随有一连串的抖动,假如不加以处理,会导致按键被识别为按下多次。
为了不产生这种现象而作的措施就是按键消抖。
3消抖的方法按键消抖分为硬件消抖和软件消抖。
3.1硬件消抖在键数较少时可用硬件方法消除键抖动。
下图所示的RS触发器为常用的硬件去抖。
硬件消抖电路图图中两个“与非”门构成一个RS触发器。
当按键未按下时,输出为0;当键按下时,输出为1。
此时即使用按键的机械性能,使按键因弹性抖动而产生瞬时断开(抖动跳开B),只要按键不返回原始状态A,双稳态电路的状态不改变,输出保持为0,不会产生抖动的波形。
也就是说,即使B点的电压波形是抖动的,但经双稳态电路之后,其输出为正规的矩形波。
这一点通过分析RS触发器的工作过程很容易得到验证。
3.1软件消抖方法1:使用延时如果按键较多,常用软件方法去抖,即检测出键闭合后执行一个延时程序,5ms~10ms 的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。
当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。
方法2:检测多次可以设定一个检测周期,如果在一个检测周期内,按键被检测为被按下达到了一定次数,则确认为真正被按下。
按键消抖
一、按键消抖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 按键消抖电路的设计按键消抖一般采用硬件和软件消抖两种方法。
硬件消抖是利用电路滤波的原理实现,软件消抖是通过按键延时来实现。
数码管从0开始自动加1+按键调速
/**************************************************************河南工业大学电气工程学院测控1001刘欣如有错误欢迎致电hellohaut@共同学习共同进步***************************************************************//****************************************************************程序名称: 数字自动加1计数,数码管显示出来按键可以调节速度说明:使用本程序你必须把 SE5设置为ON(2-3)短接P11按键为停止计数按键 P10为速度减1档 P34为速度加1档P33为暂停或开始计数按键*****************************************************************//*头文件*/#include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define ulong unsigned long int/*端口定义*/#define sled_dm_port P0 /*定义LED显示的段码数据脚*/#define sled_wm_port P2 /*定义LED显示的位码数据脚*/sbit P10 = P1^0; //p1.0脚定义为速度减1档sbit P11 = P1^1; //p1.1脚定义为停止键sbit P33 = P3^3; //p3.3脚定义为暂停及开始键sbit P34 = P3^4; //p3.4脚定义为速度加1档sbit P30 = P3^0; //系统运行状态提示/*定义数码管显示字符跟数字的对应数组关系*/uchar code mun_to_char[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};/* 0 1 2 3 4 5 6 7 8 9 a b c d e f *//*定义需要点亮的数码管*/uchar code sled_bit_table[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};uchar data sled_data[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /*0-7号SLED 缓冲值*/uchar data led_lighten_bit=0 ; /*LED灯点亮标志位0-7*/uint system_count=0; //P30外接LED闪烁计数uint add_count = 0;ulong count=0; //数码管计数值uint speed=0; //计数速度uchar temp=0; //临时值uchar play=1; //计数开始 0暂停 1开始uchar add_bit = 0; //条件计数/*-----------------------------------------------显示部分程序,采用定时器0产生中断,1MS更新一次------------------------------------------------*/void SLED_Disp() interrupt 1 using 3{TH0 = (65536-1000)/256;TL0 = (65536-1000)/256;sled_wm_port = 0xff; /*关闭显示*/sled_dm_port = sled_data[led_lighten_bit]; /*输出段码数据到数码管*/sled_wm_port = sled_bit_table[led_lighten_bit]; /*输出位码数据到数码管*/ led_lighten_bit++;if(led_lighten_bit>=8) led_lighten_bit=0; /*8位数码管全动态输出*/system_count++;if(system_count>=500){P30=~P30;system_count = 0;}else if((system_count>=150)&&((P10==0)||(P11==0)||(P33==0)||(P34==0))){ //有按键按下快速闪烁P30 = ~P30;system_count = 0;}add_count++;if(add_count>=speed){add_count = 0;add_bit = 1;}}/*1MS为单位的延时程序*/void delay_1ms(uchar x){uchar j;while(x--){for(j=0;j<125;j++){;}}}void T0_valueSet() /*定义中断方式,中断时间*/{TMOD = 0x01; /*定时0,工作在方式1*/TH0 = (65536-1000)/256;TL0 = (65536-1000)/256;TR0 = 1; /*启动计数*/EA = 1; /*开总中断*/ET0 = 1; /*开定时器0中断*/return;}/*主程序*/void main(){uchar key_put_bit = 0; //按键按下,0为无按键按下,1为有按键按下T0_valueSet(); //打开显示while(1){//更新显示数据sled_data[0] = mun_to_char[count/10000000];sled_data[1] = mun_to_char[count%10000000/1000000];sled_data[2] = mun_to_char[count%1000000/100000];sled_data[3] = mun_to_char[count%100000/10000];sled_data[4] = mun_to_char[count%10000/1000];sled_data[5] = mun_to_char[count%1000/100];sled_data[6] = mun_to_char[count%100/10];sled_data[7] = mun_to_char[count%10];if((play==1)&&(add_bit==1)){ //计数加1count++;if(count>99999999) count=0; //计算超出范围,从0开始add_bit = 0;}if(((P10==0)||(P11==0)||(P33==0)||(P34==0))&&(key_put_bit==0)){ delay_1ms(2);key_put_bit = 1;if(P10==0){ //p1.0脚定义为速度减1档if((speed<=2000)) speed = speed+50;}else if(P11==0){ //p1.1脚定义为停止键count = 0; //计数清零play = 0; //置停止计数或暂停计数speed = 0; //速度归零}else if(P33==0){ //p3.3脚定义为暂停及开始键if(play==1){//暂停处理temp = speed;speed = 0;play = 0;}else if(play==0){//开始计数处理speed = temp;play = 1;}}else if(P34==0){ //p3.4脚定义为速度加1档if(speed>=50) speed = speed-50;}}if((P10!=0)&&(P11!=0)&&(P33!=0)&&(P34!=0)) key_put_bit = 0;} }。
按键消抖的原理
按键消抖的原理一、引言在电子设备中,按键是常见的输入方式。
然而,由于按键的机械结构,当按下或松开按键时,会产生机械弹跳现象,导致信号出现多次跳变,这就是所谓的“按键抖动”现象。
为了避免这种现象对电路造成干扰,需要进行按键消抖处理。
二、什么是按键消抖?按键消抖是指在接收到按键信号后,在一定时间内只处理一次信号,并且保证该信号为有效信号。
其目的是消除因机械结构引起的多次跳变信号。
三、按键消抖的原理1. 机械弹跳原理在了解按键消抖原理之前,需要先了解机械弹跳原理。
当按下或松开一个开关时,由于接触面积有限和金属表面不完全平整等因素影响,开关触点会发生不稳定震荡,并在短时间内反复接通和断开。
这种现象称为“机械弹跳”。
2. 软件处理原理软件处理原理是通过程序来实现对按键状态进行检测和判断的方式。
具体实现方法包括:轮询法、中断法、计时法等。
(1)轮询法轮询法是指通过循环检测按键状态的方式来实现按键消抖。
具体实现方法为:在主程序中设置一个循环,不断检测按键状态,当检测到按键被按下时,进行一定的延时后再次检测按键状态,如果依然是按下状态,则判断为有效信号。
(2)中断法中断法是指通过外部中断来实现对按键状态进行检测和判断的方式。
具体实现方法为:将按键连接到微控制器的外部中断引脚上,在程序中设置好相应的中断服务程序,当检测到外部中断信号时,进入相应的中断服务程序进行处理。
(3)计时法计时法是指通过定时器来实现对按键状态进行检测和判断的方式。
具体实现方法为:当检测到按键被按下时,启动定时器并开始计数,在一定时间内只处理一次信号,并保证该信号为有效信号。
四、硬件处理原理硬件处理原理是通过使用电路元件来实现对按键消抖的方式。
具体包括RC滤波器、Schmitt触发器、反相器等。
1. RC滤波器RC滤波器是将电容和电阻组合在一起,利用电容的充放电特性实现对信号的滤波。
当按键被按下时,由于电容的充放电时间常数较长,可以使机械弹跳信号被滤除。
用Verilog HDL实现按键消抖
按键消抖用按键控制一个数字,按键每按一次,这个数字加1,并通过数码管将这个数字显示出来(以16进制)。
可能是悟性比较低,按键消抖都搞了1天才搞出来,下面这个程序是我经过参考别人的(有些地方没想明白),然后自己领会,写的一个程序,经过在开发板上实验,还是有一点小问题,但是我觉得,按键消抖的原理应该是这样的。
希望本文能帮到需要的人,我也是一个初学者,可能程序中也有很多不足,还请能提出来,相互交流。
QQ:1664619265module SW_debounce(rst_n,sy_clk,key,HEX0_D);input rst_n;/低电平复位input sy_clk;//系统时钟50Mhzinput key; 按键output [6:0]HEX0_D;数码管//*************************/reg key_rst;always@(posedge sy_clk or negedge rst_n) beginif(!rst_n)key_rst<=1'b1;else每个时钟周期读一次按键的值key_rst<=key;end 将按键的值存在key_rst中//*************************/reg key_rst_r;always@(posedge sy_clk or negedge rst_n) beginif(!rst_n)key_rst_r<=1'b1;else 每个时钟周期将key_rst中的值存入key_rst_r中。
key_rst_r<=key_rst;这样key_rst和key_rst_r中存放的是前后两个时钟周期,按键的值end//*************************/wire key_en,key_an;重点1:抖动时期的标志量,这两个标志量是用来给后面的计数器清零的assign key_en=key_rst&(~key_rst_r);当按键由0变1时,key_en为1 assign key_an=key_rst_r&(~key_rst);当按键由1变0时,key_an为1;看下面的按键波形,俺觉得,抖动期间,这两个标志量都有可能为1 //**************************/reg[18:0] count; 计数,是为了延时10ms左右always@(posedge sy_clk or negedge rst_n) beginif(!rst_n)count<=19'd0;else if(key_en | key_an)count<=19'd0;出现抖动就将count清零,使其计不满,因为后面是每10ms读一次按键的值else if(count==19'h7ffff)//10mscount<=19'd0;elsecount<=count+1'b1;end//************************/reg low_sw;always@(posedge sy_clk or negedge rst_n) beginif(!rst_n)low_sw<=1'b1;else if(count==19'h7ffff)low_sw<=key;每10ms读一次按键的值,因为抖动期间,count的值是到不了7ffff的,所以抖动期间是不会读按键的值的,因此能消除抖动。
按键计数说明
“按键计数”说明(一)设计思路和方法按键计数是通过按键来控制数据的加减然后在LED数码管上进行显示,其中涉及按键消抖,每1mS(可在不同TASK中改变)查看一次按键,如果在100mS、即100次中(由NMAX_KEY定义)中有2/3(N_KEY)以上按键按下,则认为按键有效按下。
一次有效按下,仅做一次动作。
动作设计在按键按下时执行(也可编成在在按键松开后执行),本实验是在按下时执行动作,key1对应加1,key2对应减1,key3对应清0。
(二)数字钟电路原理图(三)L ED数码管电路(左边部分)(四)(五)按键电路(六)(七)电路工作原理在实验2中已经分别说明了LED数码管的电路工作原理,在实验3中已经说明按键的电路工作原理,因此这里不再复述。
这里着重讲一下按键消抖过程,通过设定按键检测统计次数,每个一段时间去检测按键值是否为0,超过统计次数的较大比例,如2/3,我们则认为按键按下,然后通过对比按键上一个状态Key_P、当前状态Key_C来确定按键动作何时进行,下降沿操作Key_P、Key_C 组合10,上升沿操作Key_P、Key_C组合01等。
(八)程序总框图设计流程如下所示(九)(十)相关寄存器配置1. P0(8位)和P2.3需要设置成推挽输出,以驱动电路正常发光。
按键作为输入,不需推挽,涉及寄存器及配置值如下:P2M1=0x00;P2M0=0xff;P0M1=0x00;P0M0=0xff;P3M0=0x00;P3M1=0x00;P1M0=0x7f;2.P1M1=0x00;3.通过定时器0,采用方式1,在定时器中断中进行计数值的累加,涉及寄存器(含可位寻址)及配置如下:AUXR |= 0x80; //定时器时钟1T模式TMOD &= 0x80; //设置定时器模式TL0 = 0xAE; //设置定时初值TH0 = 0xFB; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时IE=0x82;(十一)案例代码见“数字钟工程”(十二)测试方法1. 用STC ISP默认设置,打开工程中的HEX并下载2. 下载后观察现象为:左边3个数码管显示000,其他数码管均灭1.辅助操作:当显示为000,按下key2,显示255,在按下key2,显示254,每按一次key2,显示数字减1;按下key1,显示数字加1;按下key3,显示清零000。
EDA流水灯,数码管显示01234567,加减计数,
练习1.两位的循环彩灯,自定义的循环彩灯2.用另外的方式实现按键控制数码管加减3.设计一个在四个数码管上,显示拨码开关给定的值。
1、设计一个流水灯。
原理图设计:(8位流水灯)程序设计:(16位流水灯)module led_s(rst,clk,leds);input rst,clk;output [15:0] leds;reg [15:0] leds;reg [3:0]count;always @(posedge clk)beginif (rst)count <=16 'h00_00;elsebeginif(count==4'hf)count <=16 'h00_00;elsecount <=count+1;endendalways @(count)begincase(count)0: leds<= 16 'b0000_0000_0000_0001;1: leds<= 16 'b0000_0000_0000_0010;2: leds<= 16 'b0000_0000_0000_0100;3: leds<= 16 'b0000_0000_0000_1000;4: leds<= 16 'b0000_0000_0001_0000;5: leds<= 16 'b0000_0000_0010_0000;6: leds<= 16 'b0000_0000_0100_0000;7: leds<= 16 'b0000_0000_1000_0000;8: leds<= 16 'b0000_0001_0000_0000;9: leds<= 16 'b0000_0010_0000_0000;10: leds<=16 'b0000_0100_0000_0000;11: leds<=16 'b0000_1000_0000_0000;12: leds<=16 'b0001_0000_0000_0000;13: leds<=16 'b0010_0000_0000_0000;14: leds<=16 'b0100_0000_0000_0000;15: leds<=16 'b1000_0000_0000_0000;default: leds<=16 'hxxxx;endcaseendendmodule2、设计一个加减计数器,计数器的值在一位数码管上显示出来。
利用按键操作数码管显示
实验功能:两位数码管显示功能。
具体功能描述如下:数码管可以显示0-99两位数字,按一下加按键,数字加1;按一下减按键,数字减1。
按下清零按键,数字清零。
程序:/*-----------------------------------------------------------------------*该程序实现的是利用单片机实现两位数码管显示功能。
具体功能描述如下:*数码管可以显示0-99两位数字,按一下加按键,数字加1;按一下减按键,数字减1*此外为了方便,还添加了一个清零按钮,按下清零按钮计数归零。
*-----------------------------------------------------------------------*/#include <reg51.h>#define unchar unsigned char//宏定义#define open 0#define close 1void delayms(char m);//延时函数声明void display();//数码管显示函数声明sbit up = P2^2;//加一按钮sbit down = P2^3;//减一按钮sbit clear = P2^4;//清零按钮sbit Ledshi = P2^0;//十位数码管使能端sbit Ledge = P2^1;//个位数码管使能端unchar LedCode[]={//数码管真值表0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};char count = 0;char ge = 0;char shi = 0;void digitalTube(){if(clear == 0){delayms(10);//按键消抖,是因为实际中按键刚刚被按下时电平抖动不稳定,延时10ms让电平稳定下来再次判断即可if(clear == 0){count = 0;}}while(clear == 0){//松手检测display();}if(up == 0){delayms(10);if(up == 0){count++;if(count == 100)count = 0;}}while(up == 0){//松手检测display();}if(down == 0){delayms(10);if(down == 0){count--;if(count == (-1))count = 99;}}while(down == 0){display();}display();}void display(){//计算各数码管显示的数值ge = count%10;shi = count/10;//关闭数码管使能端,防止乱入Ledge = close;Ledshi = close;//轮流导通两位数码管P0 = LedCode[ge];Ledge = open;//打开个位数码管delayms(1);Ledge = close;P0 = LedCode[shi];Ledshi = open;delayms(1);Ledshi = close;}void delayms(char m){//延时m毫秒char i,j;for(i = 0;i < m; i++)for(j = 0;j < 110;j++); }硬件仿真电路:Welcome To Download !!!欢迎您的下载,资料仅供参考!。
8个数码管键盘按键控制
#include "reg52.h"#define uint unsigned int#define uchar unsigned charsbit key1 = P3^2;sbit key2 = P3^3;sbit key3 = P3^4;sbit key4 = P3^5;sbit key5 = P1^4;sbit key6 = P1^5;sbit key7 = P1^6;sbit key8 = P1^7;uchar code table[] = { 0x3f, 0x06, 0x5b, 0x4f,//数码管显示编码0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c,0x39, 0x5e, 0x79, 0x71 };uchar led_1=0,led_2=0,led_3=0,led_4=0,led_5=0,led_6=0,led_7=0,led_8=0; void InitPort();void Delay_ms( uint xms );void Display_LED1( void );void Display_LED2( void );void Display_LED3( void );void Display_LED4( void );void Display_LED5( void );void Display_LED6( void );void Display_LED7( void );void Display_LED8( void );void Key_Input();void main(){InitPort();for( ;; ){Display_LED1( );//上电后全部显示0(根据需要随意填写0~9)Delay_ms( 1 );Display_LED2( );Delay_ms( 1 );Display_LED3( );Delay_ms( 1 );Display_LED4( );Delay_ms( 1 );Delay_ms( 1 );Display_LED6( );Delay_ms( 1 );Display_LED7( );Delay_ms( 1 );Display_LED8( );Delay_ms( 1 );Key_Input();}}/**********************************初始化I/O端口***********************************/ void InitPort(){P0 = 0x00;//点亮数码管所有段P1 = 0xff;//没有按键按下P2 = 0x00;//选择所有数码管P3 = 0xff;}/**********************************延时子程序***********************************/ void Delay_ms( uint xms ){uint i, j;for( i = xms; i > 0; i -- )for( j = 110; j > 0; j -- );}/**********************************数码管1显示子函数***********************************/ void Display_LED1( void){P2 = 0xfe;P0 = table[ led_1 ]^0xff;}/**********************************数码管2显示子函数***********************************/{P2 = 0xfd;P0 = table[ led_2 ]^0xff;//显示数字}/**********************************数码管3显示子函数***********************************/ void Display_LED3(void ){P2 = 0xfb;P0 = table[ led_3 ]^0xff;//显示数字}/**********************************数码管4显示子函数***********************************/ void Display_LED4( void){P2 = 0xf7;P0 = table[ led_4 ]^0xff;//显示数字}/**********************************数码管5显示子函数***********************************/ void Display_LED5( void){P2 = 0xef;P0 = table[ led_5 ]^0xff;//显示数字}/**********************************数码管6显示子函数***********************************/ void Display_LED6( void){P2 = 0xdf;P0 = table[ led_6 ]^0xff;//显示数字}/**********************************数码管7显示子函数***********************************/ void Display_LED7( void){P2 = 0xbf;P0 = table[ led_7 ]^0xff;//显示数字}/**********************************数码管8显示子函数***********************************/void Display_LED8( void){P2 = 0x7f;P0 = table[ led_8 ]^0xff;//显示数字}/**********************************按键程序***********************************/void Key_Input(){if( key1 == 0 ){Delay_ms( 10 );//消除按键抖动if( key1 == 0 ){if( led_1 < 9 )//判断LED1是否超出显示范围led_1++; //如果没有超出显示范围,显示加1 else led_1 = 0;//如果超出显示范围,显示0while( !key1 );//等待按键释放}}if( key2 == 0 ){Delay_ms( 10 );//消除按键抖动if( key2 == 0 ){if( led_2 < 9 )//判断LED2是否超出显示范围led_2++; //如果没有超出显示范围,显示加1 else led_2 = 0;//如果超出显示范围,显示0while( !key2 );//等待按键释放}}if( key3 == 0 ){Delay_ms( 10 );//消除按键抖动if( key3 == 0 ){if( led_3 < 9 )//判断LED3是否超出显示范围led_3++; //如果没有超出显示范围,显示加1 else led_3 = 0;//如果超出显示范围,显示0while( !key3 );//等待按键释放}}if( key4 == 0 ){Delay_ms( 10 );//消除按键抖动if( key4 == 0 ){if( led_4 < 9 )//判断LED4是否超出显示范围led_4++; //如果没有超出显示范围,显示加1 else led_4 = 0;//如果超出显示范围,显示0while( !key4 );//等待按键释放}}if( key5 == 0 ){Delay_ms( 10 );//消除按键抖动if( key5 == 0 ){if( led_5 < 9 )//判断LED5是否超出显示范围led_5++; //如果没有超出显示范围,显示加1 else led_5 = 0;//如果超出显示范围,显示0while( !key5 );//等待按键释放}}if( key6 == 0 ){Delay_ms( 10 );//消除按键抖动if( key6 == 0 ){if( led_6 < 9 )//判断LED6是否超出显示范围led_6++; //如果没有超出显示范围,显示加1 else led_6 = 0;//如果超出显示范围,显示0while( !key6 );//等待按键释放}}if( key7 == 0 ){Delay_ms( 10 );//消除按键抖动if( key7 == 0 ){if( led_7 < 9 )//判断LED7是否超出显示范围led_7++; //如果没有超出显示范围,显示加1 else led_7 = 0;//如果超出显示范围,显示0while( !key7 );//等待按键释放}}if( key8 == 0 ){Delay_ms( 10 );//消除按键抖动if( key8 == 0 ){if( led_8 < 9 )//判断LED8是否超出显示范围led_8++; //如果没有超出显示范围,显示加1 else led_8 = 0;//如果超出显示范围,显示0while( !key8 );//等待按键释放}}}。
51单片机数码管加减
} } 这个键盘子程序的思路可以借鉴,以后 得这样用。 主程序:
void main() {
while(1) {
display(shu); keyscan(); } } 键盘,显示子程序均需要不停地扫
描。
这里要注意的是:由于要求中要满
足,不松开按键时,数字间隔增加
或减少,所以在键盘子程序中就不
能像平时一样,key 是否为 0,延时,
键盘子程序:
void keyscan() {
P1=0xff; // P1 口赋初值, key_code=P1;//将 P1 口的状态赋予一 个变量,便于以后的检测。 if(key_code!=0xff)//如果条件满足说 明有按键被按下。 {
for(i=0;i<30;i++) display(shu);//这小段子程序有两个 作用:1、不断的扫描显示子程序。这样就 会避免一种现象:按键被按下时,所有的
是否为 0,while(!key);等待按 键释放。这样写永远也实现不了功 能,这就是这个程序的巧妙之处, 以后不要死板硬套,要根据功能去 写程序。
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,通系电1,力过根保管据护线生高0不产中仅工资2艺料22高试2可中卷以资配解料置决试技吊卷术顶要是层求指配,机置对组不电在规气进范设行高备继中进电资行保料空护试载高卷与中问带资题负料2荷试2,下卷而高总且中体可资配保料置障试时2卷,32调需3各控要类试在管验最路;大习对限题设度到备内位进来。行确在调保管整机路使组敷其高设在中过正资程常料1工试中况卷,下安要与全加过,强度并看工且25作尽52下可22都能护可地1关以缩于正小管常故路工障高作高中;中资对资料于料试继试卷电卷连保破接护坏管进范口行围处整,理核或高对者中定对资值某料,些试审异卷核常弯与高扁校中度对资固图料定纸试盒,卷位编工置写况.复进保杂行护设自层备动防与处腐装理跨置,接高尤地中其线资要弯料避曲试免半卷错径调误标试高方中等案资,,料要编试求5写、卷技重电保术要气护交设设装底备备置。4高调、动管中试电作线资高气,敷料中课并设3试资件且、技卷料中拒管术试试调绝路中验卷试动敷包方技作设含案术,技线以来术槽及避、系免管统不架启必等动要多方高项案中方;资式对料,整试为套卷解启突决动然高过停中程机语中。文高因电中此气资,课料电件试力中卷高管电中壁气资薄设料、备试接进卷口行保不调护严试装等工置问作调题并试,且技合进术理行,利过要用关求管运电线行力敷高保设中护技资装术料置。试做线卷到缆技准敷术确设指灵原导活则。。:对对在于于分调差线试动盒过保处程护,中装当高置不中高同资中电料资压试料回卷试路技卷交术调叉问试时题技,,术应作是采为指用调发金试电属人机隔员一板,变进需压行要器隔在组开事在处前发理掌生;握内同图部一纸故线资障槽料时内、,设需强备要电制进回造行路厂外须家部同出电时具源切高高断中中习资资题料料电试试源卷卷,试切线验除缆报从敷告而设与采完相用毕关高,技中要术资进资料行料试检,卷查并主和且要检了保测解护处现装理场置。设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
按键加减计数(数码管显示,中断方式)
按键加减计数(数码管显⽰,中断⽅式)按键加减计数(数码管显⽰,中断⽅式)(合肥⼯⼤周宁)课程设计对象A08电⽓⼯程及⾃动化本科班,共38+39⼈。
⼀.课程设计的任务和⽬的本课程设计要求学⽣在1.5周内编程设计⼀个单⽚机应⽤系统,完成设计报告。
通过设计实践,使学⽣掌握单⽚机的应⽤特点、编程⽅法,学会单⽚机实际应⽤系统的设计开发过程及设计报告的规范书写,为毕业设计打下良好的基础。
⼆.课程设计内容及要求(⼀)、课程设计题⽬可从如下⽅⾯参考选择(⾃⼰出题的必须经⽼师批准):1.单⽚机在计时控制⽅⾯的应⽤设计。
如:时钟、频率计、彩灯、交通灯2.单⽚机在计数控制⽅⾯的应⽤设计。
如:计数器、计分器、抢答器、报警器3.单⽚机在运算控制⽅⾯的应⽤设计。
如:密码锁、计算器、乒乓球游戏机4.单⽚机在波形发⽣⽅⾯的应⽤设计。
如:电⼦琴、⾳乐盒、调光LED灯5.单⽚机在通讯技术⽅⾯的应⽤设计。
如:双机通讯、PC可控单⽚机系统、对话机器⼈6.单⽚机A/D转换技术⽅⾯的应⽤设计。
如:电压表、温度计、照度计(⼆)、具体要求:1.完成控制程序的编制,能演⽰系统功能。
2.完成设计并上交纸质设计报告1份。
3.系统功能要求及设计报告格式范⽂见附件1、附件2。
三.时间与学时安排1.课程设计时间在本学期第16-17周(共1.5周)。
2.总体教学时间安排:课程设计成绩按学⽣设计报告按五级评分制综合评定。
六.评分标准1.设计报告:按版⾯格式、⽂字语法、观点正确性、图表规范性等综合评分。
机电⼯程学院电⽓系胡佳⽂2010年12⽉12⽇附件1:单⽚机原理与应⽤课程设计功能要求1.单⽚机在计时控制⽅⾯应⽤的设计功能要求:(1)时钟能计时,可校准时间,⾄少有⼀种附带功能(如秒表、定时器或闹钟功能);(2)频率计能测试并显⽰1HZ—10KHZ频率、5V的⽅波,可附带⽅波发⽣器功能;(3)彩灯要求控制16个LED有两种以上闪烁⽅式;(4)交通灯要求模拟控制⼗字路⼝交通信号,有倒计时显⽰。
浅谈动态扫描数码管“消抖”、“消影”问题
浅谈动态扫描数码管“消抖”、“消影”问题最近工作的需要,又涉及到了数码管的动态扫描问题。
在此把其中需要注意的地方记录一下,总结一下,也和爱好电子朋友们分享一下,由其是当代的大学生们,及那些刚刚踏入这一领域的新手们。
虽然简单,但也值的注意。
以下所述为无锁存,三极管驱动的共阳四位一体的数码管。
问题1:动态扫描时,有抖动。
对这个问题,相信很多人会说,有抖动那就说明你扫描的太慢了呗,增加扫描的频率不就可以了吗?那此时,请问一下自己,扫描的频率是多少才合适呢?在网上看到一些“大牛”谈到不能低于每秒24次的频率,对于4位数码管来说,也就是10.4ms/位。
按照这个频率我试了一下,发现显示有抖动,没办法,可能是程序上有些臃肿吧(有高手的话,还请指点下),只好再往高调些。
想到以前那种大头显示器的,显示频率为65Hz以上,对于4位数码管来说,可以折算成3.4ms/位。
当然人家显示器比数码管复杂多了,这个拿这儿来肯定是嫌快了,10.4ms/位的咱做不到,5ms/位的咱还做不到吗?经过试验5ms/位的显示效果还是相当不错的,不管是从数码管的亮度还是抖动方面来说,都是没问题的。
而5ms的中断对大多数程序来说也是有足够空间的,一般也不会出现什么中断冲突的情况。
问题2:动态扫描时,不显示的段有暗红。
对于这个问题,很多人会说,你扫描的太快了呗,不知道有余辉啊,不知道人有眼睛有视觉暂留效应啊?其实不然,这里关键的一点在于“消影”,这一点对于大学生来说,可能会很陌生,因为教科书上根本不会提,大部分资料上也不写,只是在程序中有这样的代码。
所谓的“消影”,其实就是要你在显示下一位前,把上一位关断。
因为单片机的IO口,在高低电平转换时,是需要时间的。
而我们要做的,就是避开这一边沿时间。
说完技术上的,也写点自己的感想。
其实对于大多数的学生来说,大家都做过数码管的动态扫描程序。
大家可能是因为,当时实验环境中有寄存器,也可能是对自己没有太高的要求,出结果就行,因而忽略了很多的细节问题。
单片机实验3LDE数码管动态显示与按键去抖程序
1、MAIN.ASM;====变量定义段====CS0 BIT P2.0 ;个位位选CS1 BIT P2.1 ;十位位选CS2 BIT P2.2 ;百位位选CS3 BIT P2.3 ;千位位选CS4 BIT P2.4 ;LED灯位选DSW EQU 30H ;位选计数DSB0 EQU 31H ;显示缓冲单元个位DSB1 EQU 32H ;显示缓冲单元十位DSB2 EQU 33H ;显示缓冲单元百位DSB3 EQU 34H ;显示缓冲单元千位DSB4 EQU 20H ;显示缓冲单元指示灯状态LD1 BIT DSB4.0 ;指示灯LD1控制位LD2 BIT DSB4.1 ;指示灯LD2控制位LD3 BIT DSB4.2 ;指示灯LD3控制位LD4 BIT DSB4.3 ;指示灯LD4控制位LD5 BIT DSB4.4 ;指示灯LD5控制位LD6 BIT DSB4.5 ;指示灯LD6控制位LD7 BIT DSB4.6 ;指示灯LD7控制位LD8 BIT DSB4.7 ;指示灯LD8控制位KEY EQU 21H ;键状态字SW1 BIT KEY.6 ;SW1键SW2 BIT KEY.7 ;SW2键EKEY EQU 22H ;键前沿字ESW1 BIT EKEY.6 ;SW1键前沿ESW2 BIT EKEY.7 ;SW2键前沿KTMR EQU 35H ;键去抖延时器AJS1 EQU 40H ;每按一次SW1,(AJS2:AJS1)+1 AJS2 EQU 41H ;每按一次SW2,(AJS2:AJS1)-1 ;====常数定义段====;==================ORG 0000HLJMP MAINORG 0030HMAIN: INCLUDE "INITIAL.INC"MLOOP: LCALL DELAY ;延时5msLCALL RDKEY ;读键LCALL DISPJNB ESW1,M03 ;无SW1键转移MOV R6,#00HMOV R7,#01HSJMP M05M03: JB ESW2,M04 ;有SW2键转移LJMP MLOOPM04: MOV R6,#99HMOV R7,#99HM05: MOV A,AJS1 ;(AJS2:AJS1)十进制±1ADD A,R7DA AMOV AJS1,AMOV A,AJS2ADDC A,R6DA AMOV AJS2,AMOV A,AJS1 ;(AJS2:AJS1)送显示ANL A,#0FHMOV DSB0,AMOV A,AJS1SW AP AANL A,#0FHMOV DSB1,AMOV A,AJS2ANL A,#0FHMOV DSB2,AMOV A,AJS2SW AP AANL A,#0FHMOV DSB3,ALJMP MLOOP;====延时子程序(2*R7+3)*R6+5=5ms====DELAY: MOV R6,#0AHDL01: MOV R7,#0F8HDL02: DJNZ R7,DL02DJNZ R6,DL01RET;====通用子程序段====INCLUDE "RDKEY.ASM";添加读键状态及去抖处理子程序INCLUDE "DISP.ASM" ;添加数码管动态扫描显示子程序END2、INITIAL.INCMOV SP,#5FHMOV R0,#20HMOV R7,#60HCLR AM01: MOV @R0,A ;存储器20H-7FH清零INC R0DJNZ R7,M01MOV DSB0,#03HMOV DSB1,#01HMOV DSB2,#01HMOV DSB3,#07HMOV R4,#0C8HM02: LCALL DELAYLCALL DISP ;显示"7113"1秒DJNZ R4,M02CLR AMOV DSB0,AMOV DSB1,AMOV DSB2,AMOV DSB3,AEND3、RDKEY.ASM;====读独立按键子程序(延时去抖)==== RDKEY: ORL P1,#0C0H ;先置1,后读口MOV A,P1 ;读键ANL A,#0C0H ;接独立键盘的位保留XRL A,#0C0H ;求反转正逻辑MOV R7,A ;新的键状态暂存R7CJNE A,KEY,RDK0 ;键状态变化则转移MOV KTMR,#05H ;去抖延时器加载初值SJMP RDK1RDK0: MOV A,KTMR ;过了延时时间?JZ RDK1DEC KTMR ;延时未结束MOV R7,KEY ;放弃不稳定的键状态RDK1: MOV A,KEY ;键前沿提取XRL A,R7ANL A,R7MOV EKEY,AMOV KEY,R7 ;启用键的新状态RETEND4、DISP.ASM;====5位数码管扫描子程序====DISP: ORL P2,#1FH ;关闭数码显示器MOV A,DSW ;根据扫描循环变量转移ANL A,#07HRL AMOV DPTR,#DSTABJMP @A+DPTRDSTAB: AJMP DIS0AJMP DIS1AJMP DIS2AJMP DIS3AJMP DIS4AJMP DIS0AJMP DIS0AJMP DIS0DIS0: MOV A,DSB0 ;扫描个位数码管ANL A,#0FHMOV DPTR,#LED7 ;查显缓个位值的七段码表MOVC A,@A+DPTRMOV P0,A ;七段码送P0口CLR CS0 ;点亮个位数码管MOV DSW,#01H ;扫描指针指向下十位RETDIS1: MOV A,DSB1 ;扫描十位数码管ANL A,#0FHMOV DPTR,#LED7MOVC A,@A+DPTRMOV P0,ACLR CS1MOV DSW,#02HRETDIS2: MOV A,DSB2 ;扫描百位数码管ANL A,#0FHMOV DPTR,#LED7MOVC A,@A+DPTRMOV P0,ACLR CS2MOV DSW,#03HRETDIS3: MOV A,DSB3 ;扫描千位数码管ANL A,#0FHMOV DPTR,#LED7MOVC A,@A+DPTRMOV P0,ACLR CS3MOV DSW,#04HRETDIS4: MOV A,DSB4 ;扫描指示灯CPL AMOV P0,ACLR CS4MOV DSW,#00HRET;====LED段码表====LED7: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H DB 80H,90H,88H,83H,86H,0A1H,86H,8EHEND。
实验05按键消抖
实验5 按键消抖1. 实验目的1. 掌握QuartusII的硬件描述语言设计方法2. 了解同步计数器的原理及应用3. 设计一个带使能输入、进位输出及同步清零的增1四位N (N<16)进制同步计数器2. 准备知识在按键使用的过程中,常常遇到按键抖动的问题,开关在闭合(断开)的瞬间,不能一接触就一直保持导通(断开),因为开关的机械特性,重要经历接触-断开-再接触-再断开,最终稳定在接触位置,这就是开关的抖动,即虽然只是按下按键一次然后放掉,结果在按键信号稳定前后,竟出现了一些不该存在的噪声,这样就会引起电路的误动作。
在很多应用按键的场合,要求具有消抖措施。
按键抖动与开关的机械特性有关,其抖动期一般为5-10ms。
图5.1 按键电平抖动示意图按键的消除抖动分为硬件消除抖动和软件消除抖动。
硬件消除抖动一般采用滤波的方法,通常在按键两端并联一个1~10u左右的电容,有时这样也不能完全消除按键的抖动。
软件消除抖动的方法有多种,常用的是延时扫描和定时器扫描。
延时扫描其原理为:检测到按键操作后延时一端时间(如10ms)后,再检测是否为仍然为同样的按键操作状态,如果相同,就认为是进行了按键操作,然后对该操作进行相应的处理。
定时器扫描的原理是:每隔一端时间(几毫秒)扫描一次键盘,如果连续两次(或3次)的所获得的按键状态相同,就输出按键状态,然后再对这种按键状态进行处理,这里的扫描时间间隔和连续判断按键状态的次数是有关系的,一般总时间要大于按键的抖动期。
如果总时间太长,则感觉按键迟钝,太短可能不能完全消除抖动,要根据实际的情况合适的选择。
在实际电路设计中,经常采用的是软硬件相结合对按键进行消除抖动的处理方法。
本实验采用的方法:实验箱按键的硬件电路是共阳极电路,按下按键时输出到FPGA管脚的电平为低电平,松开按键时为高电平。
我们采用5ms的定时器扫描FPGA管脚电平,如果连续3次为低电平时,存储连续按键状态的次数CNT的值加1,直到该计数值等于10(或再大一些),就不再累加(防止长按该值溢出而重新计数),此时认为按键已稳定,输出按键操作标志;在该过程中,一旦FPGA管脚电平为低电平就对CNT复位清零并同时对按键操作标志位复位,即一个异步复位。
EDA流水灯,数码管显示01234567,加减计数,
练习1.两位的循环彩灯,自定义的循环彩灯2.用另外的方式实现按键控制数码管加减3.设计一个在四个数码管上,显示拨码开关给定的值。
1、设计一个流水灯。
原理图设计:(8位流水灯)程序设计:(16位流水灯)module led_s(rst,clk,leds);input rst,clk;output [15:0] leds;reg [15:0] leds;reg [3:0]count;always @(posedge clk)beginif (rst)count <=16 'h00_00;elsebeginif(count==4'hf)count <=16 'h00_00;elsecount <=count+1;endendalways @(count)begincase(count)0: leds<= 16 'b0000_0000_0000_0001;1: leds<= 16 'b0000_0000_0000_0010;2: leds<= 16 'b0000_0000_0000_0100;3: leds<= 16 'b0000_0000_0000_1000;4: leds<= 16 'b0000_0000_0001_0000;5: leds<= 16 'b0000_0000_0010_0000;6: leds<= 16 'b0000_0000_0100_0000;7: leds<= 16 'b0000_0000_1000_0000;8: leds<= 16 'b0000_0001_0000_0000;9: leds<= 16 'b0000_0010_0000_0000;10: leds<=16 'b0000_0100_0000_0000;11: leds<=16 'b0000_1000_0000_0000;12: leds<=16 'b0001_0000_0000_0000;13: leds<=16 'b0010_0000_0000_0000;14: leds<=16 'b0100_0000_0000_0000;15: leds<=16 'b1000_0000_0000_0000;default: leds<=16 'hxxxx;endcaseendendmodule2、设计一个加减计数器,计数器的值在一位数码管上显示出来。
按键控制数码管增减
单片机两位数码显示器,并根据端口的接线情况编写相应的程序,使其具有以下功能:
1.单片机系统具有双向循环显示功能,两位数码管采用十进制,最大显示
值是99,最小显示值是00,
2.按下S1后,数码管的数值自动增1;(00—99)
3.按下S2后,数码管的数值自动减1;(99—00)
4.按下S3时,数码管停止递增或递减,并显示当时的数值;
5.数码管数值自动增、减时间间隔T 0.5S<T<1S。
评定内容:
1.组装好单片机部分
2.组装好数码管部分
3.组装好电源部分
4.单片机及数码管能够工作
5.按键S1工作正常
6.按键S2工作正常
7.按键S3工作正常
8.数码管数字在改变时没有闪烁。