基于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();//启动函数
  }
 }

posted @ 2020-05-17 13:46  吃不了就兜着走  阅读(1445)  评论(0编辑  收藏  举报