按键控制数码管0-99显示,十位不跳,用定时器T0中断

如果直接在主函数中写按键控制数码管0-99显示,不管怎么延时数码管十位上的数都会闪,原因就是单片机的机器周器太快,人的按键速度是ms级的,所以等你人操作完了,单片机早就执行了不知道多少遍。

解决方法就是用中断,这里采用定时器T0溢出中断,工作方式1, 2ms中断显示一次,这样的话既不影响按键操作,又不影响显示,一举两得。


以下程序是适用于德飞莱51单片机开发板


#include <reg52.h>


#define uint unsigned int
#define uchar unsigned char
#define DataPort P0 


sbit Seg_Latch = P2^2;    //段锁存
sbit Bit_Latch = P2^3;    //位锁存


sbit key_up = P1^0;      //数字增加按键
sbit key_down = P1^1;    //数字减少按键


uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //数码管显示0-9


uchar code tab[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};    //数码管位选


uchar temp[2];   //存放num十位和个位


void Display(unsigned char FirstBit,unsigned char Num);  //显示函数


void delay(uchar t)  //延时
{
while(--t);
}


void DelayMs(uchar z) //ms级延时
{
while(z--)
{
delay(245);
delay(245);
}
}


void Time0_init()    //定时器T0溢出中断初始化
{
TMOD |= 0x01;      //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
EA = 1;
ET0 = 1;
TR0 = 1;
}


char num = 0;         //0-99数字
uchar key_num = 0;    //按键计数


void main()
{
Time0_init();     //T0中断初始化
key_up = 1;       //使用前先拉高
key_down = 1;
while(1)
{
if(!key_up)
{
DelayMs(10);
if(!key_up)
{
while(!key_up)
{
key_num++;
DelayMs(10);    //10x100 = 1s 按了1s
if(key_num == 100)
{
key_num = 0;    //清零
while(!key_up)
{
if(num < 99)
{
num++;
}
temp[0] = table[num / 10];//及时赋值
temp[1] = table[num % 10];
DelayMs(50);   //数字跳动快慢
}
}
}
key_num = 0;   //防止累加造成错误识别
if(num < 99)
{
num++;
}
}
}

if(!key_down)    //减操作
{
DelayMs(10);
if(!key_down)
{
while(!key_down)
{
key_num++;
DelayMs(10);
if(key_num == 100)
{
key_num = 0;
while(!key_down)
{
if(num > 0)
{
num--;
}
temp[0] = table[num / 10];
temp[1] = table[num % 10];
DelayMs(50);
}
}
}
key_num = 0;
if(num > 0 )
{
num--;
}
}
}
temp[0] = table[num / 10];   //用完赋值
temp[1] = table[num % 10];
}
}


void Display(unsigned char FirstBit,unsigned char Num)    //显示
{
  static unsigned char i = 0;  //静态局部变量,用完后不释放
   DataPort  = 0;   
   Seg_Latch = 1;     
   Seg_Latch = 0;


   DataPort = tab[i+FirstBit]; 
   Bit_Latch=1;     
   Bit_Latch=0;


   DataPort = temp[i]; 
   Seg_Latch=1;     
   Seg_Latch=0;

i++;
if(i == Num)
{
i = 0;
}
}


void Time0_isr() interrupt 1
{
TH0 = (65536 - 2000) / 256;   //取高八位 2ms
TL0 = (65536 - 2000) % 256;   //取低八位
Display(0,2);
}
  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下的代码实现单片机按键控制数码管显示00-99: ```c #include <reg52.h> // 引入头文件 sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; unsigned char code table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 // 数码管显示0-9的编码表 }; void delay(unsigned int i) // 延时函数 { while(i--); } void main() { unsigned int i=0, j=0; // 定义两个变量用于存储数值 P0=0; LSA=0;LSB=0;LSC=0; // 数码管显示0 while(1) { if(P3!=0xff) // 当按键被按下时 { delay(1000); // 延时,避免按键抖动 if(P3!=0xff) // 再次检测按键是否被按下 { if(P3==0xfe) // 如果按下K1键 { i++; // 数值加1 if(i>99) i=0; // 如果数值大于99,重新从0开始 } if(P3==0xfd) // 如果按下K2键 { j++; // 数值加1 if(j>99) j=0; // 如果数值大于99,重新从0开始 } } } P0=table[i/10]; // 将十位数码管的编码输出到P0口 LSA=1;delay(5);LSA=0; // 显示十位数码管 P0=table[i%10]; // 将个位数码管的编码输出到P0口 LSB=1;delay(5);LSB=0; // 显示个位数码管 P0=table[j/10]; // 将十位数码管的编码输出到P0口 LSC=1;delay(5);LSC=0; // 显示十位数码管 P0=table[j%10]; // 将个位数码管的编码输出到P0口 LSA=1;delay(5);LSA=0; // 显示个位数码管 } } ``` 这段代码中,P2.2、P2.3 和 P2.4 分别连接到数码管的 LSA、LSB 和 LSC 引脚,P0 口连接到数码管的 a~g 引脚。通过检测按键是否被按下,来改变 i 和 j 两个变量的数值,从而控制数码管显示

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值