基于51单片机四位一体数码管显示短按加或减数值及长按连加或连减数值

//按键短按加或减,长按连加或连减,四位一体数码管显示0~9999。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define key_short 10//宏定义短按20ms
#define key_long 50//宏定义长按100ms
#define key_middle 40//宏定义长按间隔80ms
sbit led=P1^4;//启停指示灯
sbit addkey=P3^0;//位定义加键
sbit deckey=P3^2;//位定义减键
sbit qiting=P3^4;//位定义启动按键端口
sbit tingzhi=P3^6;//位定义停止按键端口
//uchar i;//数码管位数变量
uchar flag;//显示函数标志位变量
uchar qitingnum;//声明启停次数变量
uint num;//数值变量
uint addcount,deccount;//计数变量
uint qian,bai,shi,ge;//定义拆字变量
//uchar code weima[]={0xfe,0xfd,0xfb,0xf7};//数码管位码表
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
/**ms级延时子程序**/
  void delay(uint x)
{
   uint i,j;                       
   for(i=0;i<x;i++)     
    for(j=0;j<110;j++);
  }
  void display()
{
   qian=num/1000;//转速/10000的余数/1000得到千位
   bai=num%1000/100;//取得百位
   shi=num%100/10;//取得十位数字
   ge=num%10;//取得个位数字

   P2=0xfe;//数码管千位显示位
   P0=table[qian];//数码管千位数值显示
   delay(2);//延时

   P2=0xfd;//数码管百位显示位
   P0=table[bai];//数码管百位数值显示
   delay(2);//延时

   P2=0xfb;//数码管十位显示位
   P0=table[shi];//数码管十位数值显示
   delay(2);//延时

   P2=0xf7;//数码管个位显示位
   P0=table[ge];//数码管个位数值显示
   delay(2);//延时
}
  void qidongkeyscan()//启动函数
{
   if(qiting==0)
 {
    delay(15);
    if(qiting==0)
  {
     qitingnum++;
     TR0=1;
     flag=0;
     while(qiting==1);
    }
   }
 }
  void tingzhikeyscan()//关掉函数
{
   if(tingzhi==0)
 {
    delay(15);
    if(tingzhi==0)
  {
     led=1;
     flag=1;
     TR0=0;
     P2=0xff;
     P0=0x00;
     qitingnum=0;
     while(tingzhi==1);
    }
   }
 }
  void keyscan()//设置函数
{
   if(qitingnum==1)
 {
    led=0; 
    if(!addkey)
  {
     addcount++;
//   delay(10);
     if(addcount>=key_long)//增加长按
   {
      if(num<9999)
      num++;        
      addcount=key_middle;//为什么存在addcount=key_middle,由于一直按着按键,addcount计数会溢出,设定addcount=key_middle能让addcount在这个addcount=key_middle基础上反复累积计数,从而不会出现计数溢出的情况。
     }
    }
     else
   {
      if(key_short<addcount&&addcount<key_long)//增加短按,为什么不可以是key_short<addcount<key_long,假若是key_short<addcount<key_long,就相当于按键还没按下,条件已经满足,按键再按下去就没意义啦。
    {
       if(num<9999)
       num++;        
      }
      addcount=0;
    }
    if(!deckey)
  {
     deccount++;
//   delay(10);
     if(deccount>=key_long)//减少长按
   {
      if(num>0)
      num--;        
      deccount=key_middle;//为什么存在deccount=key_middle,由于一直按着按键,deccount计数会溢出,设定deccount=key_middle能让addcount在这个deccount=key_middle基础上反复累积计数,从而不会出现计数溢出的情况。
     }
    }
     else
   {
      if(key_short<deccount&&deccount<key_long)//减少短按,为什么if条件不可以是key_short<deccount<key_long,假若是key_short<deccount<key_long,就相当于按键还没按下,条件已经满足,按键再按下去就没意义啦。
    {
       if(num>0)
       num--;        
      }
      deccount=0;
    }
   }
  }
//  void display()//显示程序
//{
//// static uchar i;
//   P0=0x00;
//   P2=weima[i];
//   switch(i)
// {
//    case 0: 
//           P0=table[num/1000]; 
//           break;
//    case 1: 
//           P0=table[num%1000/100]; 
//           break;
//    case 2: 
//           P0=table[num%100/10];
//           break;
//    case 3: 
//           P0=table[num%10]; 
//           break;
//  }
//   i++;
//   i%=4;
// }
  /**定时器0初始化子程序**/
  void Time0_init()
{
   TMOD=0X01;//模式选定时器0、计数器1,工作方式选定时器0定时模式1、计数器1计数模式1。
   TH0=(65536-5000)/256;//定时器0高8位定时50毫秒
   TL0=(65536-5000)%256;//定时器0低8位定时50毫秒
   EA=1;//打开总中断
   ET0=1;//打开定时器0的中断
   TR0=0;//打开定时器0
  }
  void Timer0() interrupt 1//定时器0中断子程序
{
   TH0=(65536-5000)/256;//重装定时器0高8位定时50毫秒
   TL0=(65536-5000)%256;//重装定时器0低8位定时50毫秒
   keyscan();//设置函数
   if(flag==0)
   display();//显示函数
   tingzhikeyscan();//关掉函数
  }
  void main()//主函数
{
   Time0_init();//定时器0初始化子程序
   while(1)
 {
    qidongkeyscan();//启动函数
  }
 }

基于51单片机四位一体数码管显示短按加或减数值及长按连加或连减数值

上一篇:setPreferredSize和setSize的区别及用法


下一篇:Qt通用方法及类库7