⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time-led.c

📁 基于AT89S51或者52系列单片机的电子时钟程序
💻 C
字号:
// K1 为加  K2为减 K3为切换键 k4为时间设置键
// 初始显示是秒 第一次按K1后显示 分钟 再按就显示时钟 如此循环 

#include <reg51.h>
#include <intrins.h>

unsigned char  dis_digit;
unsigned char  key_s,key_v,temp1,temp2;  
unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0,	// 0, 1, 2, 3
				0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off 
unsigned char  dis_buf[2];                           
unsigned char  dis_index;                            
         char hour,min,sec;                                
unsigned char sec100; 
unsigned char key3_times;

sbit	K1 = P1^4;
sbit	K2 = P1^5;
sbit	K3 = P1^6;
sbit    K4 = P1^7;

bit scan_key();
void proc_key();
void inc_sec();
void inc_min();
void inc_hour();
void dec_sec();
void dec_min();
void dec_hour(); 
void display();
void delayms(unsigned char ms);

void main(void)
{
	P0 = 0xff;
	P2 = 0xff;
	TMOD = 0x11;		// 定时器0, 1工作模式1, 16位定时方式                    
	TH1 = 0xdc;                              
	TL1 = 0;

	TH0 = 0xFC;                           
	TL0 = 0x17;                            
	
	hour=0x00;
	min =0x00;
	sec =0x00;

	sec100 = 0;
    key_v=0x0f;                             
	key3_times=0x00;
	dis_digit = 0x7f;                     
	dis_index = 0;     

    dis_buf[1] = dis_code[0];		
   	dis_buf[0] = dis_code[0];	
	
    TCON = 0x01;
	IE = 0x8a;				// 使能timer0,1 中断
	
	TR0 = 1;
	TR1 = 1;

	

	while(1)
	{
	     
             if(scan_key())
		{
                  delayms(10);
		  key_v = key_s;
                  
                  proc_key();
                  
                }
		
	}
}

bit scan_key()
{   
        key_s = 0x00;                                    
        temp1=0x00;                                    
        temp2=0x00;     
	key_s|=K4;                               
 	temp1|= K3;              
        key_s|=temp1<<3;          
        temp2|=K2;             
        key_s|=temp2<<2;         
	key_s |= K1;              
	return(key_s ^ key_v);    
  
}

void proc_key()
{ 
     EA = 0 ;
     if((key_v & 0x04) == 0)     
      {  
	     key3_times++;
	     if(key3_times>0x02)    key3_times=0;
       }
	 
     if(key3_times==0x00)
       {  
          if((key_v & 0x01) == 0) inc_sec();
          if((key_v & 0x02) == 0) dec_sec();
        }

      else  if(key3_times==0x01) 
          {
           if((key_v & 0x01) == 0) inc_min();
           if((key_v & 0x02) == 0) dec_min();
           }

      else  {
           if((key_v & 0x01) == 0) inc_hour();
           if((key_v & 0x02) == 0) dec_hour();              
            }
     EA = 1 ;
}

void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
//				选通P2.0口数码管
// dis_buf   --- 显于缓冲区基地址	
{
	TH0 = 0xFC;
	TL0 = 0x17;
	
	P2 = 0xff;
    if(key3_times==0)                                       
 	{
          dis_buf[1] = dis_code[sec / 10];		// 秒十位
   	      dis_buf[0] = dis_code[sec % 10];		// 秒个位
         }

    else  if(key3_times==0x01)                            
          {   
           dis_buf[1] = dis_code[min / 10];		// 分十位
	       dis_buf[0] = dis_code[min % 10];		// 分个位
          }
         
       else{
             if(hour <10) 
             {  dis_buf[1] = 0xff;                                             
                dis_buf[0] = dis_code[hour% 10]; 
               }
            else{ dis_buf[1] = dis_code[hour / 10];		// 时十位	         
                  dis_buf[0] = dis_code[hour% 10];		// 时个位	
                  } 
            }
        						// 先关闭所有数码管
	 P0 = dis_buf[dis_index];			// 显示代码传送到P0口
	 P2 = dis_digit;						// 

	dis_digit = _cror_(dis_digit,1);	// 位选通值右移, 下次中断时选通下一位数码管
	dis_index++;						// 
					
	if(dis_index==0x02) 		  // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
        { dis_digit=0x7f;        
          dis_index=0x00;
         }	
} 

void timer1() interrupt 3
{
	TH1 = 0xdc;
	
	sec100++;
	
	if(sec100 >= 100)
	{
		sec100 = 0;
		inc_sec();
	}
}

void inc_hour()
{
	hour++;
	if(hour > 23)
	{
		hour = 0;
	}
	
   
	dis_buf[1] = dis_code[hour / 10];		// 时个位
        dis_buf[0] = dis_code[hour %10];
}

void dec_hour()
{
	hour--;
	if(hour <0)
	{
		hour = 23;
	}
	
	dis_buf[1] = dis_code[hour / 10];		// 时个位
        dis_buf[0] = dis_code[hour %10];
  }

void inc_sec()
{
	sec++;
	if(sec > 59)
	{
		sec = 0;
		inc_min();
	}
	dis_buf[1] = dis_code[sec / 10];		// 秒十位
	dis_buf[0] = dis_code[sec % 10];		// 秒个位	
}

void dec_sec()
{
	sec--;
	if(sec <0)
	{
		sec = 59;
		dec_min();
	}
	dis_buf[1] = dis_code[sec / 10];		// 秒十位
	dis_buf[0] = dis_code[sec % 10];		// 秒个位	
}

void inc_min()
{
	min++;
	if(min > 59)
	{
		min = 0;
		inc_hour();
	}   
	dis_buf[1] = dis_code[min / 10];		// 分十位
	dis_buf[0] = dis_code[min % 10];		// 分个位
}

void dec_min()
{
         min--;
	if(min < 0)
        {
	 min = 59;
	 }
	dis_buf[1] = dis_code[min / 10];		// 分十位
	dis_buf[0] = dis_code[min % 10];		// 分个位
}



void delayms(unsigned char ms)	
// 延时子程序
{						
	unsigned char i;
	while(ms--)
	{
		for(i = 0; i < 120; i++);      
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -