请教高手,用51单片机独立按键控制数码管数字加减,为什么在按下独立按键的时候会出现闪烁?怎么回事?

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-03
51单片机C语言程序4个独立按键实现对数码管数字显示的加减清零等

#include //P0是数码管。P1是LED.P2是按键sbit KEY_OUT_1 = P2^3;sbit KEY_OUT_2 = P2^2; sbit KEY_OUT_3 = P2^1;sbit KEY_OUT_4 = P2^0;#define uchar unsigned char#define ulint unsigned long#define Frequency 10//定时器中断时间 = f*T#define Time 1//一个周期1ms#define TubeNumber 6//数码管个数#define KeyLine 4//矩阵按键行数 #define KeyColumn 4//矩阵按键列数 //数码管真值表uchar code LED_Number[]={0x0C,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//uchar code LED_Alphabet[]={0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0x8C,0xC1,0x91,0x9C};/*0~9 A~F (b 、d为小写) H L P U y o */uchar LED_Buff[TubeNumber]={0xff,0xff,0xff,0xff,0xff,0xff};/*数码管显示缓冲区,0xff确保初始时都不亮.不可写成uchar code LED_Buff[]。code定义变量写入room,不可修改*/// 矩阵按键编号到标准盘码的映射表 uchar code KeyCodeMap[4][4] = { ( 0x31, 0x32, 0x33, 0x26 ), // 数字键 1、数字键 2、数字键 3、向上键( 0x34, 0x35, 0x36, 0x25 ), // 数字键 4、数字键 5、数字键 6、向左键 ( 0x37, 0x38, 0x39, 0x28 ), // 数字键 7、数字键 8、数字键 9、向下键 ( 0x30, 0x1B, 0x0D, 0x27 )}; // 数字键 0、ESC 键 、回车键 、向右键uchar StaFlag[KeyLine][KeyColumn] ={(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按键是否稳定标志 void StartTime0();void TubeDisplay(ulint sec);ulint pow(x,y);void TubeScan();void KeyAction(uchar keycode);void KeyDriver();void KeyScan();void main (){P1 = 0x08;//使能U3,选择数码管。StartTime0();while(1)KeyDriver();}//定时器0启动函数void StartTime0(){EA = 1;ET0 = 1;TMOD = 0x01;TH0 = (65536 - Time * 100) / 256;TL0 = (65536 - Time * 100) % 256;PT0 = 1;/*定时器0优先中断控制位。IP 这个寄存器的每一位,表示对应中断的抢占优先级,每一位的复值都是0,当我们把某一位设置为1的时候,这一位优先级就比其它位的优先级高了。比如我们设置了 PT0位为1后, 当单片机在主循环或其他中断程序执行时,一旦TO发生中断,作为更高优先级,程序马上执行T0.若在T0程序执行时,其他中断程序发生中断,仍执行TO直到T0中断结束后再执行其他程序。 */ }//中断服务函数 void To_time0()interrupt 1 using 0{static uchar cnt;//记录TO中断次数//static ulint sec;//记录经过秒速//判断是否溢出 if (TF0 == 1){TF0 = 0;TH0 = (65536 - Time * 100) / 256;TL0 = (65536 - Time * 100) % 256;}if (cnt >= Frequency){cnt = 0;//sec++;//Tube_Display(sec);TubeScan();KeyScan();}}//数码管显示函数void TubeDisplay(ulint nom){uchar m = 2;//小数部分位数uchar i;//传输索引//秒速达到上限清零if (nom > pow(10,TubeNumber - m))nom = 0;//分别传输小数部分和整数部分 for(i=0; i= TubeNumber)i=0;//索引递增循环,遍历整个缓冲区} //矩阵按键动作函数void KeyAction(uchar keycode){static ulint result;ulint nom = 0;//输入数字0~9 if ((keycode >= 0x30) && (keycode = 0x25) && (keycode > (4 + l)) & 0x01));//按键消抖 for(l=0; l <KeyLine; l++){if((keybuff [l][c] & 0x0f) == 0x00)//连续4次扫描都为0,判断4*4ms内都是按下状态,可认为按键已稳定按下StaFlag[l][c] = 0;else if ((keybuff [l][c] & 0x0f) == 0x0f)//连续4次扫描都为1,判断4*4ms内都是弹起状态,可认为按键已稳定弹起 StaFlag[l][c] = 1;}for(c=0; c <KeyColumn; c++){switch (c) // 根据索引,释放当前输出脚 拉低下次的根据索引{ case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; }}}

void keyScan() //1*5按键扫描函数
{
P3 = P3 | 0xf8; //P3高5位置1,设置为输入,默认为高电平 0xf8=11111000
keyValue = P3;
if((keyValue & 0xf8) != 0xf8) { //判断是否有按键按下
delay(20); //延时肖抖
keyValue = P3;
if((keyValue & 0xf8) != 0xf8) //再次判断是否有按键按下
keyValue &= 0xf8; //读取扫描结果
}
}

因为你按键的时候影响了数码管刷新;

数码管一般都是动态扫描的,利用人眼的视觉暂留做的,你按下按键的时候,肯定有延时消抖,延时的时候就影响了数码管显示,所以数码管刷新的慢了,人眼就能分辨出来亮和灭的状态....

解决办法
1、改进按键扫描
2、改进数码管显示
3、用嵌入式系统

以上三选一即可解决

因为你的按键没有作消抖处理。

要销抖,并且要判断按下和松开的动作.

按键的时候也要扫描数码管。

  • 51单片机怎样实现不同独立按键按下出现不同情况
    答:实现该功能的操作步骤参考如下:1、先将每个独立按键连接到51单片机的不同输入引脚上,并通过下拉电阻将其拉低。2、在程序中,使用循环或定时器中断的方式不断读取每个按键的引脚状态。当某个按键被按下时,其对应的引脚电平会变为高电平。3、根据读取到的按键引脚状态,执行相应的操作。例如,如果按键A...
  • 请教高手,用51单片机独立按键控制数码管数字加减,为什么在按下独立按...
    答:1、改进按键扫描 2、改进数码管显示 3、用嵌入式系统 以上三选一即可解决
  • 51单片机中用数码管做秒表时怎么用一个独立按键控制开始和暂停,即第一...
    答:要做秒表,一定要用定时器吧,假如用T0,那开始初始化时,不写TR0=1,先不启动。\x0d\x0a当按一下键,再启动,TR0=1,就开始计时了。\x0d\x0a再 按一下键,就停止,TR0=0,就不计时了。\x0d\x0a程序好写,先 定义一个按键\x0d\x0asbit key=P1^1; //具体是哪个 键,...
  • ...然后用一个独立按键控制这个脉冲信号的启动与停止,可以循环操作_百度...
    答:51单片机,用一个IO口模拟一个脉冲信号,然后用一个独立按键控制这个脉冲信号的启动与停止,可以循环操作 循环操作就是按一下IO口开始输出脉冲,再按一下脉冲停止,再按一下又开始输出脉冲。。。如此往复。脉冲信号我用定时器模拟的,但是用一个按键实在是不会控制启动和停止。初学者,困扰... 循环操作就是按一下IO...
  • 我用51单片机控制一个机械手臂搬运物料,求问用一个独立按键,采用外部...
    答:刚刚为你编写的 已经在单片机上测试成功 原理是,按键第一次被按下后,nn为1,程序一直在中断里面死循环 这样其它指令就暂停了,而中断的原理既是,从哪断开的,就回到那里 在这个死循环中,检测按键时候又被按下 按键又按下后,nn变为0,死循环的条件不满足 ...
  • 51单片机如何把矩阵键盘控制数码管和独立键盘控制蜂鸣器共同实现_百度...
    答:具体的思路是:首先使行作为输入,使用单片机内部电阻上拉为高电平,列输出低电平,读行的状态。如果行有一个IO口是低,说明有键按下,进行下一步,否则退出扫描。如果有键按下,置列为输入,行输出低电平,读列的状态。最后根据 行列的状态查表就可以知道是那个按键按下。
  • 求解读51单片机用四个按键独立控制四个led的c程序
    答:include<reg51.h>//k2~k4 分别控制le1~le4 void delay(unsigned int x) //延时函数{ while(x--); //延时数减一} void key_event (unsigned char d) //根据扫描到的键值,亮相应的LED { switch(d) { case 14: P1^=(1<<0); break; //k1 键按下了 case 13: P1^=...
  • 51单片机怎么用按键控制一个数码管,按一下显示一个数字,顺序显示
    答:1、首先,要把代码写好,点亮数码管。2、代码写完后,要确认原先写好的代码是不是正确的。3、确认代码无误后,进入下一步,就是在这一行代码(箭头所指)的地方,将这四个字删去。4、然后如图所示,四个字已经删去,只要改成数字相应的代码即可。5、这里改成的是代表数字0的代码,如图所示。6、...
  • 51单片机独立按键怎么控制3个独立程序(有独立头文件的程序) 程序我写...
    答:把三个独立的程序,写成3个子程序,都放在一个程序中,在主程序中,判断3个按键,当按下3个按键后,分别执行相应的子程序就行了。
  • 51单片机控制数码管显示时钟,独立按键怎么弄
    答:独立按键处理起来是非常简单的,一般都是IO口单独控制,所以只需要消抖和判断按键按下抬起状态就好。比如:sbit key=P1^0;if(key==0){ delay(10); if(key==0) { keyval=1; while(key==0); }}