51单片机 定时器实现数码管显示0-999间隔1秒 按键实现不同功能

单片机小白用的ben方法,请大佬多多指教!

数码管间不能同时进行赋值显示,要用到扫描刷新。
每个数码管显示字符后留影一段时间, while(1)扫描可以让数码管一直刷新显示,让人的眼睛误以为数码管是同时显示的,实际上每个数码管是一亮一灭的,合适的刷新时间可以欺骗人的眼睛。

因程序总是从主函数开始自上而下串行的,数码管刷新时间与间隔一秒再自增冲突(3根数码管显示不同步),所以将数码管刷新函数加至定时器延迟函数中

独立按键一:按下数码管显示数值增加(>999变000)
独立按键二:按下数码管显示数值减少(<000变999)
独立按键三:按下数码管显示数值清零及退出0-999的自增
独立按键四:按下数码管显示0-999的自增,间隔1秒

程序中函数的调用有点多,所以精度可能会有些许偏差。

代码部分:

#include <reg52.h>


sbit button1=P3^1;
sbit button2=P3^0;
sbit button3=P3^2;
sbit button4=P3^3;   //按钮进行位定义

sbit add_1=P2^2;
sbit add_2=P2^3;    
sbit add_3=P2^4;     //将3个控制选中数码管的引脚进行位定义
                     /*这3个引脚(可赋值0/1)经74LS138译码后可得到8个结果(2^3=8),分别对应八个数码管*/
char x,y,n;   //x,y,n要进行进制转换所以不能用unsigned char
unsigned char code a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管显示0-9的字符数组
	 
//有参定时器延时函数     1.25ms*参数=总延时时间
void delay_ds(unsigned char ms)
  {
    unsigned char T=0;
    TMOD=0x01;   //定时器方式一 16位定时器计数器   容器最大数2^16=65536
    TH0=0xfb;    //初值的高位
    TL0=0x80;    //初值的低位
    TR0=1;       //定时器启动
    while(T<ms)
    {
     if(TF0==1)      //溢出标志位,溢出时硬件自动赋1,不能软件赋值
	   {
	    TF0=0;       //溢出后重新赋值为0后定时器可以重新计数
	  	TH0=0xfb;
        TL0=0x80;    // 初值fb80换算成十进制为64384  每次加1直到大于65536后溢出需要1.25ms
		 T++;        //while循环里面语句循环ms次(ms为参数)
	   }
    }
    
  }//1.25*ms

	
//  三根数码管刷新
void shuaxin()
 {
	 add_1=0;
	 add_2=1;
	 add_3=0;       //选中第三根数码管
	 P0=a[y];
    delay_ds(3);    //留影时间3.75ms
     P0=0x00;	    //消影
    			
	 add_1=1;
	 add_2=0;
	 add_3=0;       //选中第二根数码管
     P0=a[x];
    delay_ds(3);	
     P0=0x00;
					  
	 add_1=0;
     add_2=0;
     add_3=0;       //选中第一根数码管
	 P0=a[n];   
	 delay_ds(3);	
	 P0=0x00;
 }	/*   
  数码管的留影时间为调用一次delay_ds(ms)函数的延时时间
 调用了3次delay_ds(ms)函数,总的刷新一次需要3*3*1.25=11.25ms
*/
	

//无参定时器延时带刷新函数 一秒
void Ding_shi01()
  { 
    unsigned char T=0;
    TMOD=0x01;   //定时器方式一  容器最大数65536
    TH0=0xfb;
    TL0=0x80;    //1.25ms
	shuaxin();   //11.25ms            12.5ms
    TR0=1;
    while(T<79)
    {
     if(TF0==1)
	  {
	    TF0=0;
	    TH0=0xfb;    
        TL0=0x80;    // 初值fb80换算成十进制为64384  每次加1直到大于65536后溢出需要1.25ms
		shuaxin();   //11.25ms          12.5ms*79=987.5ms
		 T++;
	   }
    }
  }
  
	
//十进制加
void jia()
 {
     if(n>9)
	  {
	    x++;
        n=0;	
	     if(x>9)
	      {
		    x=0;
			y++;
			 if(y>9)
				y=0;
		  }
	  }
 }
 
 //十进制减
void jian()
 {
	 if(n<0)
	  { 
		x--;
        n=9;	
		 if(x<0)
	      { 
		    x=9;
		    y--;
		     if(y<0)
		        y=9;
		  }
	  }
 }
  

void main()
{  
	  
   button1=0xff;
   button2=0xff; 
   button3=0xff;
   button4=0xff;//初始按键要赋1
   
   y=x=n=0;/*y为控制右边第三根数码管字符的变量
             x为控制右边第二根数码管字符的变量
             n为控制右边第一根数码管字符的变量
             将y,x,n都赋值为0*/
	
   while(1)
   {       
       
	 shuaxin(); //因y,x,n初值为0,如不进行以下其他操作,3根都会一直显示000
	 
	 //按下数码管显示数值增加
     if(button1==0) //按键按下确定
	    {
	     delay_ds(2); //按键消抖
	     if(button1==0)//按键按下再次确定
	     {
	       while(!button1)//当一直按键按下将会一直运行以下代码,即n一直自增直到松下按键
	        { 
			    shuaxin();//按下按键数值增加的延迟时间带刷新
			    n++;	
				jia();
		    }
	     }
	    }
			
	   //按下数码管显示数值减少
	   if(button2==0)
	    {
	     delay_ds(2);
	     if(button2==0)
	     {
	       while(!button2)
          {
			    shuaxin();	
				n--;			
			    jian();
          }
	    
    	 }
	   }
		
			
	    //按下数码管显示数值清零及退出0-999的自增
		if(button3==0)
	    {
	     delay_ds(2);
	     if(button3==0)
	     {
	       while(!button3)
           {
				while(1)
				{
					x=y=n=0;//将下x,y,n赋值为0
			        shuaxin();	
					if(button1==0||button2==0||button4==0)
					  break; //按下其他键跳出while循环,即可进行其他操作

		       }
	      }
	     }	
	    }			
		 
		//按下从0自增至999,间隔1秒
		if(button4==0)
	    {
	     delay_ds(2);
	     if(button4==0)
	     {  
				 
	       while(!button4)
	       {   
				 for(y=0;y<10;y++)
				  {
				   if(button3==0)
				       break; //按下第三颗按键可跳出for循环,即退出从0自增至999
					 for(x=0;x<10;x++)
					  {
					   if(button3==0)
					       break;
			             for(n=0;n<10;n++)
			             { 
						    if(button3==0)
						  	    break;
					    	Ding_shi01(); //定时器延迟带刷新函数 1秒
			             }
				      }
			       }
			      y=x=n=0; //从0自增至999后数码管显示000
			 }
					 
				   
     } 
			  
	  }

	}
	    
			

		
	    
			
			
 }



 

  • 11
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值