单片机–数码管(138译码器)显示日期

软件部分

#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;
typedef unsigned long u32;

sbit BZ=P1^5;	 

sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;


u32 s=0;
u16 Second=60,Miunte=59,Hour=23;	 //秒 分 时 变量
u16 count;


sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//显示0~F的值

 void delay(u16 i)
{
	while(i--);	
}

/******************************************************************************* * 函 数 名 : keyscan * 函数功能 : 设置时钟数;k1分加,k2分减,k3秒加,k4秒减 *******************************************************************************/
void keyscan()
{
	if(k1==0)
	{
		delay(1000);
		if(k1==0)
		{
	    	Hour++;
			if(Hour==24)
			Hour=0;
		}
		while(!k1);
	}
	if(k2==0)
	{		
		delay(1000);
		if(k2==0)
	   { 
	   		Hour--;
	   		if(Hour==-1)
			Hour=23;
	   }		
	   	while(!k2);
	}
	if(k3==0)
	{
		delay(1000);
		if(k3==0)
		{
	    	Miunte++;
			if(Miunte==60)
			Miunte=0;

		}
		while(!k3);
	}
	if(k4==0)
	{		
		delay(1000);
		if(k4==0)
	   {
	    	Miunte--;
			if(Miunte==-1)
			Miunte=59;
	   }		
	   	while(!k4);
	}
}
/******************************************************************************* * 函 数 名 : DigDisplays3 * 函数功能 : 控制时钟“秒”,―00 *******************************************************************************/
void DigDisplayS3(u16 num)
{
	u8 i;
	u8 digbuff[3];
	digbuff[2]=16;
	digbuff[1]=num/10%10;
	digbuff[0]=num%10;

	for(i=0;i<3;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=0;LSB=0;LSC=0; break;//显示第0位
			case(1):
				LSA=1;LSB=0;LSC=0; break;//显示第1位
			case(2):
				LSA=0;LSB=1;LSC=0; break;//显示第2位

		}
		P0=smgduan[digbuff[i]];//发送段码
		delay(100); //间隔一段时间扫描 
		P0=0x00;//消隐
	}
}
/******************************************************************************* * 函 数 名 : DigDisplayM3 * 函数功能 : 控制时钟“分”,―00 *******************************************************************************/
void DigDisplayM3(u16 num)
{
	u8 i;
	u8 digbuff[3];
	digbuff[2]=16;
	digbuff[1]=num/10%10;
	digbuff[0]=num%10;

	for(i=0;i<3;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{

			case(0):
				LSA=1;LSB=1;LSC=0; break;//显示第3位
			case(1):
				LSA=0;LSB=0;LSC=1; break;//显示第4位
			case(2):
				LSA=1;LSB=0;LSC=1; break;//显示第5位
		}
		P0=smgduan[digbuff[i]];//发送段码
		delay(100); //间隔一段时间扫描 
		P0=0x00;//消隐
	}
}
/******************************************************************************* * 函 数 名 : DigDisplayH2 * 函数功能 : 控制时钟“时”,00 *******************************************************************************/
void DigDisplayH2(u16 num)
{
	u8 i;
	u8 digbuff[2];
	digbuff[1]=num/10%10;
	digbuff[0]=num%10;

	for(i=0;i<2;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=0;LSB=1;LSC=1; break;//显示第6位
			case(1):
				LSA=1;LSB=1;LSC=1; break;//显示第7位 
		}
		P0=smgduan[digbuff[i]];//发送段码
		delay(100); //间隔一段时间扫描 
		P0=0x00;//消隐
	}
}


/******************************************************************************* * 函 数 名 : Timer0Init * 函数功能 : 定时器0初始化 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Timer0Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;           //打开定时器总中断
	ET0=1;			//开通定时器T0中断
	TR0=1;			//定时器0开始计时
}
/******************************************************************************* * 函 数 名 : Timer1Init * 函数功能 : 定时器1初始化 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Timer1Init(void)		//500微秒@12.000MHz
{
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC0;		//设置定时初值
	TH1 = 0xFE;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;
	ET1=1;
}
/******************************************************************************* * 函 数 名 : nz * 函数功能 : 整点响15s * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void nz()
{
	if(Miunte==0)	
	{
		if(Second<16)
		   {
				TR1=1;
			}
		else  TR1=0;
	}
	else  TR1=0;
}
/******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void main()
{	
	Timer0Init();  //定时器0初始化
	Timer1Init(); //定时器1初始化
	while(1)
	{
		keyscan();
		DigDisplayS3(Second);
		DigDisplayM3(Miunte);
		DigDisplayH2(Hour);
		nz();
	}		
}

/******************************************************************************* * 函 数 名 : void Timer0() interrupt 1 * 函数功能 : 定时器0中断函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Timer0() interrupt 1
{
	
	TH0=0XFC;	//给定时器赋初值,定时1ms
	TL0=0X18;
	count++;
	if(count==1000)
	{
		count=0;
		Second++;
		if(Second==60)
		{	
			Second=0;
			Miunte++;
			if(Miunte==60)
			  {
			  	Miunte=0;
			   	Hour++;
			   	if(Hour==24)
			  	 {
				  Hour=0;
				 }
			  }
		}
			
	}	
}

void Timer1() interrupt 3
{			  
	TL1 = 0x0C;		//设置定时初值 //给定时器赋初值,定时500us
	TH1 = 0xFE;		//设置定时初值
	BZ=~BZ;
}

参考资料

  1. 基于138译码器的数码管的资料https://blog.csdn.net/weixin_43599390/article/details/105206999
  2. 百度百科https://baike.baidu.com/item/74LS138/7761037?fr=aladdin
  3. 普中单片机论坛http://prechin.net/