286 基于单片机数码管动态显示万年历设计(电路 程序 报告)

完整版 电路图和程序代码 下载地址

https://pan.baidu.com/s/1DEeLkidDxWFqs-c98673tw?pwd=8888

部分代码展示
#include <REGX51.H>
#define uchar unsigned char
#define uint     unsigned int
sbit DATA=P1^2;            //数据(PA0)
sbit SCK=P1^0;             //移位时钟(PA1)
sbit RCK=P1^1;            //锁存时钟(PA2)
sbit P20=P2^0;
sbit P21=P2^1;
sbit P33=P3^3;
sbit  DS1302_CLK = P1^7;              //实时时钟时钟线引脚 
sbit  DS1302_IO  = P1^6;              //实时时钟数据线引脚 
sbit  DS1302_RST = P1^5;//实时时钟复位线引脚
sbit  ACC0 = ACC^0;
sbit  ACC7 = ACC^7;
char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;  //秒,分,时到日,月,年位闪的计数
sbit Set = P3^0;       //模式切换键
sbit Up = P3^1;        //加法按钮
sbit Down = P3^2;      //减法按钮
sbit out = P3^4;       //立刻跳出调整模式按钮
 
char done,count,temp,flag,up_flag,down_flag;
uchar DS1302[8]={4,5,6,7,8,6,9};  //秒,分,时,日,月,星期,年 
uint f; 
 
 uchar t[14]; 
uchar k;
uchar code Seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void display(uchar L1,uchar L2,uchar L3,uchar L4,uchar L5,uchar L6,uchar L7,uchar L8,
  uchar L9,uchar L10,uchar L11,uchar L12,uchar L13,uchar L14);
/***********DS1302时钟部分子程序******************/
typedef struct __SYSTEMTIME__
{
	unsigned char Second;
	unsigned char Minute;
	unsigned char Hour;
	unsigned char Week;
	unsigned char Day;
	unsigned char Month;
	unsigned char  Year;
	unsigned char DateString[14]; 
}SYSTEMTIME;	//定义的时间类型
SYSTEMTIME CurrentTime;


 
#define DS1302_SECOND	0x81          //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE	0x83
#define DS1302_HOUR		0x85 
#define DS1302_WEEK		0x8A
#define DS1302_DAY		0x87
#define DS1302_MONTH	0x89
#define DS1302_YEAR		0x8D 

void DS1302InputByte(unsigned char d) 	//实时时钟写入一字节(内部函数)
{ 
    unsigned char i;
    ACC = d;
    for(i=8; i>0; i--)
    {
        DS1302_IO = ACC0;           	//相当于汇编中的 RRC
        DS1302_CLK = 1;
        DS1302_CLK = 0;
        ACC = ACC >> 1; 
    } 
}

unsigned char DS1302OutputByte(void) 	//实时时钟读取一字节(内部函数)
{ 
    unsigned char i;
    for(i=8; i>0; i--)
    {
        ACC = ACC >>1;         			//相当于汇编中的 RRC 
        ACC7 = DS1302_IO;
        DS1302_CLK = 1;
        DS1302_CLK = 0;//在下降沿数据从移位寄存器输出
    } 
    return(ACC); 
}

void Write1302(unsigned char ucAddr, unsigned char ucDa)	//ucAddr: DS1302地址, ucData: 要写的数据
{
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;//只有在clk为低时,才能将rst置高
    DS1302InputByte(ucAddr);       	// 地址,命令 
    DS1302InputByte(ucDa);       	// 写1Byte数据
    DS1302_CLK = 1;//上升沿将数据写入DS1302内部移位寄存器
    DS1302_RST = 0;
} 

unsigned char Read1302(unsigned char ucAddr)	//读取DS1302某地址的数据
{
    unsigned char ucData;
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;//启动数据传送
    DS1302InputByte(ucAddr|0x01);        // 地址,命令 ,读操作
    ucData = DS1302OutputByte();         // 读1Byte数据,应在上升沿前读取
    DS1302_CLK = 1;
    DS1302_RST = 0;
    return(ucData);
}



void DS1302_GetTime(SYSTEMTIME *Time)  //获取时钟芯片的时钟数据到自定义的结构型数组
{
	unsigned char ReadValue;
	ReadValue = Read1302(DS1302_SECOND);
	Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//16进制转为10进制
 ReadValue = Read1302(DS1302_MINUTE);
	Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
	ReadValue = Read1302(DS1302_HOUR);
	Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
	ReadValue = Read1302(DS1302_DAY);
	Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);	
	ReadValue = Read1302(DS1302_WEEK);
	Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
	ReadValue = Read1302(DS1302_MONTH);
	Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
	ReadValue = Read1302(DS1302_YEAR);
	Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);	
}
void DateToStr(SYSTEMTIME *Time)    //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{   if(hide_year<5)                 //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22
    {                               
	  Time->DateString[0] = 2;
	  Time->DateString[1] = 0;	 
	  Time->DateString[2] = Time->Year/10;
	  Time->DateString[3] = Time->Year%10;
	}
	  else
	    { 
	     		 
	      Time->DateString[2] =10 ;
	      Time->DateString[3] =10 ;
		}
 
	if(hide_month<5)
	{
	  Time->DateString[4] = Time->Month/10;
	  Time->DateString[5] = Time->Month%10;
	}
	  else
	  {
	    Time->DateString[4] =10;
	    Time->DateString[5] =10;
	  }
 
	if(hide_day<5)
	{
	  Time->DateString[6] = Time->Day/10;
	  Time->DateString[7] = Time->Day%10;
	}
	  else
	  {
	    Time->DateString[6] =10;
	    Time->DateString[7] =10;	    
	  }
 


    if(hide_hour<5)
    {
	  Time->DateString[8] = Time->Hour/10;
	  Time->DateString[9] = Time->Hour%10;
	}
	  else
	    {
	      Time->DateString[8] =10;
	      Time->DateString[9] =10;
		}
 
    if(hide_min<5)
	{
	  Time->DateString[10] = Time->Minute/10;
	  Time->DateString[11] = Time->Minute%10;
	}
	  else
	    {
	      Time->DateString[10] =10;
	      Time->DateString[11] =10;
   	    }
	 
    if(hide_sec<5)
    {
	  Time->DateString[12] = Time->Second/10 ;
	  Time->DateString[13] = Time->Second%10 ;
    }
      else
       {
         Time->DateString[12] =10;
	     Time->DateString[13] =10;
       }
 
}
void show_time()   //显示程序
{     uchar i;
   uchar j;
  
DS1302_GetTime(&CurrentTime);  //获取时钟芯片的时间数据
     DateToStr(&CurrentTime);
    for(j=0;j<14;j++) 
 {t[j]=Seg[CurrentTime.DateString[13-j]];}
    
     RCK=0;//锁存置低
 
       
for(j=0;j<14;j++)
{
  for(i=0;i<8;i++)             
       {
       SCK=0;           //移位脉冲置低
       DATA=t[j]&0x80;
       t[j]=t[j]<<1; 
       SCK=1;//上升沿时数据寄存器的数据移位
	   }
      } 
            
       
  RCK=1;    //上升沿时移位寄存器的数据进入数据存储寄存器           
      
 } 

 /*延时子程序*/
void mdelay(uint delay)
{	uint i;
 	for(;delay>0;delay--)
   		{for(i=0;i<62;i++) //1ms延时.
       		{;}
   		}
}


void outkey()                    //跳出调整模式,返回默认显示
{ uchar Second;
  if(out==0)         
  { mdelay(8); 
	count=0;
	hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
	Second=Read1302(DS1302_SECOND);
 
	Write1302(0x80,Second&0x7f);
 
	done=0;           
	while(out==0);
 
  }
}

void Upkey()//升序按键
{	   
		Up=1;
		if(Up==0)
		          {
				   mdelay(8);
 
				       switch(count)
				          {/*case 1:
                                  temp=Read1302(DS1302_SECOND);  //读取秒数
								  temp=temp+1;  //秒数加1
                                  up_flag=1;    //数据调整后更新标志
								  if((temp&0x7f)>0x59)   //超过59秒,清零
                                  temp=0;								  
				

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值