首页
到顶部
到尾部
单片机毕业设计

电子万年历的设计

分享到
时间:2015/3/15 14:37:23  作者:  来源:  查看:256  评论:0
内容摘要:.infoad {FLOAT: left; MARGIN:3px; }ar ucData;    DS1302_RST = 0;    DS1302_CLK = 0;    DS1302_R...

ar 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);

    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<2)                 //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22

    {   Time->DateString[0] = '2';

      Time->DateString[1] = '0';   

      Time->DateString[2] = Time->Year/10 + '0';

      Time->DateString[3] = Time->Year%10 + '0';}

      else{  Time->DateString[0] = ' '; Time->DateString[1] = ' ';     

          Time->DateString[2] = ' '; Time->DateString[3] = ' ';}

    Time->DateString[4] = '/';

    if(hide_month<2)

    {Time->DateString[5] = Time->Month/10 + '0';

      Time->DateString[6] = Time->Month%10 + '0';}

      else{ Time->DateString[5] = ' '; Time->DateString[6] = ' ';}

    Time->DateString[7] = '/';

    if(hide_day<2)

    {Time->DateString[8] = Time->Day/10 + '0';

      Time->DateString[9] = Time->Day%10 + '0';}

      else{Time->DateString[8] = ' ';Time->DateString[9] = ' ';     }

    if(hide_week<2){

      week_value[0] = Time->Week%10 + '0';  //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示}

      else { week_value[0] = ' ';}

      week_value[1] = '\0';

    Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符}

void TimeToStr(SYSTEMTIME *Time)  //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];

{   if(hide_hour<2)

    { Time->TimeString[0] = Time->Hour/10 + '0';

      Time->TimeString[1] = Time->Hour%10 + '0';}

      else{ Time->TimeString[0] = ' ';Time->TimeString[1] = ' ';}

    Time->TimeString[2] = ':';

if(hide_min<2){ Time->TimeString[3] = Time->Minute/10 + '0';

      Time->TimeString[4] = Time->Minute%10 + '0';}

      else {Time->TimeString[3] = ' ';Time->TimeString[4] = ' '; }

    Time->TimeString[5] = ':';

    if(hide_sec<2)

    {Time->TimeString[6] = Time->Second/10 + '0';

      Time->TimeString[7] = Time->Second%10 + '0';}

      else{Time->TimeString[6] = ' ';Time->TimeString[7] = ' '; }

    Time->DateString[8] = '\0';}

void Initial_DS1302(void)   //时钟芯片初始化

{   unsigned char Second=Read1302(DS1302_SECOND);

    if(Second&0x80)       //判断时钟芯片是否关闭     

    {Write1302(0x8e,0x00); //写入允许

    Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55

    Write1302(0x88,0x07);Write1302(0x86,0x25);

    Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);

    Write1302(0x80,0x55);Write1302(0x8e,0x80); //禁止写入}}

void Delay1ms(unsigned int count)

{unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);}

/*延时子程序*/

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(0x8e,0x00); //写入允许

    Write1302(0x80,Second&0x7f);

    Write1302(0x8E,0x80);          //禁止写入

    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;                                   break;

  case 2:

temp=Read1302(DS1302_MINUTE);  //读取分数

 temp=temp+1;  //分数加1

up_flag=1;

if(temp>0x59)          //超过59分,清零

temp=0;break;

case 3:

 temp=Read1302(DS1302_HOUR);  //读取小时数

temp=temp+1;  //小时数加1

up_flag=1;

if(temp>0x23)   //超过23小时,清零

 temp=0; break;

 case 4:

                                  temp=Read1302(DS1302_WEEK);  //读取星期数

                                  temp=temp+1;  //星期数加1

                                  up_flag=1;

                                  if(temp>0x7) 

                                  temp=1;

                                  break;

                           case 5:

                                  temp=Read1302(DS1302_DAY);  //读取日数

                                  temp=temp+1;  //日数加1

                                  up_flag=1;

                                  if(temp>0x31)

                                  temp=1;

                                  break;

                           case 6:

                                  temp=Read1302(DS1302_MONTH);  //读取月数

                                  temp=temp+1;  //月数加1

                                  up_flag=1;

                                  if(temp>0x12)

                                  temp=1;

                                  break;

                           case 7:

                                  temp=Read1302(DS1302_YEAR);  //读取年数

                                  temp=temp+1;  //年数加1

                                  up_flag=1;

                                  if(temp>0x85)

                                  temp=0;

                                  break;

                           default:break;}

while(Up==0); }}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Downkey()//降序按键

{       Down=1;if(Down==0)

                  { mdelay(8);

                     switch(count)

                          {case 1:

                                  temp=Read1302(DS1302_SECOND);  //读取秒数

                                  temp=temp-1;            //秒数减1

                                  down_flag=1;       //数据调整后更新标志

                                  if(temp==0x7f)     //小于0秒,返回59秒

                                  temp=0x59;

                                  break;

                           case 2:

                                  temp=Read1302(DS1302_MINUTE);  //读取分数

                                  temp=temp-1;  //分数减1

                                  down_flag=1;

                                  if(temp==-1)

                                  temp=0x59;      //小于0秒,返回59秒

                                  break;

                           case 3:

                                  temp=Read1302(DS1302_HOUR);  //读取小时数

                                  temp=temp-1;  //小时数减1

                                  down_flag=1;

                                  if(temp==-1)

                                  temp=0x23;

                                  break;

                           case 4:

                                  temp=Read1302(DS1302_WEEK);  //读取星期数

                                  temp=temp-1;  //星期数减1

                                  down_flag=1;

                                  if(temp==0)

                                  temp=0x7;;

                                  break;

                           case 5:

                                  temp=Read1302(DS1302_DAY);  //读取日数

                                  temp=temp-1;  //日数减1

                                  down_flag=1;

                                  if(temp==0)

                                  temp=31;

                                  break;

                           case 6:

                                  temp=Read1302(DS1302_MONTH);  //读取月数

                                  temp=temp-1;  //月数减1

                                  down_flag=1;

                                  if(temp==0)

                                  temp=12;

                                  break;

                           case 7:

                                  temp=Read1302(DS1302_YEAR);  //读取年数

                                  temp=temp-1;  //年数减1

                                  down_flag=1;

                                  if(temp==-1)

                                  temp=0x85;

                                  break;

                          default:break;}while(Down==0); }}

void Setkey()//模式选择按键

{Set=1;if(Set==0)

        { mdelay(8); count=count+1; //Setkey按一次,count就加1

           done=1;          //进入调整模式

           while(Set==0);    }}

void keydone()//按键功能执行

{        uchar Second;

         if(flag==0)    //关闭时钟,停止计时

         { Write1302(0x8e,0x00); //写入允许

           temp=Read1302(0x80);

           Write1302(0x80,temp|0x80);

           Write1302(0x8e,0x80); //禁止写入

           flag=1; }

         Setkey();                          //扫描模式切换按键

         switch(count)

         {case 1:do                         //count=1,调整秒

                  { outkey();              //扫描跳出按钮

                   Upkey();                //扫描加按钮

                   Downkey();              //扫描减按钮

                   if(up_flag==1||down_flag==1)  //数据更新,重新写入新的数据

                   {

                   Write1302(0x8e,0x00); //写入允许

                   Write1302(0x80,temp|0x80); //写入新的秒数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0; }

  hide_sec++;          //位闪计数

                   if(hide_sec>3)

                     hide_sec=0;

                   show_time();         //液晶显示数据

                  }while(count==2);break; 

          case 2:do                         //count=2,调整分

                  { hide_sec=0;

                   outkey();

                   Upkey();

                   Downkey();

                   if(temp>0x60)

                     temp=0;

                   if(up_flag==1||down_flag==1)

                   { Write1302(0x8e,0x00); //写入允许

                   Write1302(0x82,temp); //写入新的分数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0; }

                   hide_min++;

                   if(hide_min>3)

                     hide_min=0;

                   show_time();

                  }while(count==3);break;

          case 3:do                         //count=3,调整小时

                  { hide_min=0;

                   outkey();

                   Upkey();

                   Downkey();

                   if(up_flag==1||down_flag==1)

                   { Write1302(0x8e,0x00); //写入允许

                   Write1302(0x84,temp); //写入新的小时数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0; }

                   hide_hour++;

                   if(hide_hour>3)

                     hide_hour=0;

                   show_time();

                  }while(count==4);break;

          case 4:do                         //count=4,调整星期

                  { hide_hour=0;

                   outkey();

                   Upkey();

                   Downkey();

                   if(up_flag==1||down_flag==1)

                   { Write1302(0x8e,0x00); //写入允许

                   Write1302(0x8a,temp); //写入新的星期数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0;}

                   hide_week++;

                   if(hide_week>3)

                     hide_week=0;

                   show_time();

                  }while(count==5);break;

          case 5:do                         //count=5,调整日

                  {hide_week=0;

                   outkey();

                   Upkey();

                   Downkey();

                   if(up_flag==1||down_flag==1)

                   {Write1302(0x8e,0x00); //写入允许

                   Write1302(0x86,temp); //写入新的日数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0; }

                   hide_day++;

                   if(hide_day>3)

                     hide_day=0;

                   show_time();

                  }while(count==6);break;

          case 6:do                         //count=6,调整月

                  { hide_day=0;

                   outkey();

                   Upkey();

                   Downkey();

                   if(up_flag==1||down_flag==1)

                   { Write1302(0x8e,0x00); //写入允许

                   Write1302(0x88,temp); //写入新的月数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0; }

                   hide_month++;

                   if(hide_month>3)

                     hide_month=0;

                   show_time();

                  }while(count==7);break;

          case 7:do                         //count=7,调整年

                  { hide_month=0;

                   outkey();

                   Upkey();

                   Downkey();

                   if(up_flag==1||down_flag==1)

                   { Write1302(0x8e,0x00); //写入允许

                   Write1302(0x8c,temp); //写入新的年数

                   Write1302(0x8e,0x80); //禁止写入

                   up_flag=0;

                   down_flag=0; }

                   hide_year++;

                   if(hide_year>3)

                     hide_year=0;

                   show_time();

                  }while(count==8);break;

          case 8: count=0;hide_year=0;  //count8, 跳出调整模式,返回默认显示状态

                  Second=Read1302(DS1302_SECOND);

                  Write1302(0x8e,0x00); //写入允许

                  Write1302(0x80,Second&0x7f);

                  Write1302(0x8E,0x80);          //禁止写入

                  done=0;

          break; //count=7,开启中断,标志位置0并退出

          default:break; }}

void show_time()   //液晶显示程序

{ DS1302_GetTime(&CurrentTime);  //获取时钟芯片的时间数据

  TimeToStr(&CurrentTime);       //时间数据转换液晶字符

  DateToStr(&CurrentTime);       //日期数据转换液晶字符

  GotoXY(0,1);

  Print(CurrentTime.TimeString); //显示时间

  GotoXY(0,0);

  Print(CurrentTime.DateString); //显示日期

  GotoXY(15,0);

  Print(week_value);             //显示星期

  GotoXY(11,0);

  Print("Week");    //在液晶上显示字母 week

  Delay1ms(400);                 //扫描延时}

main()

{ flag=1;           //时钟停止标志

    LCD_Initial();    //液晶初始化

    Initial_DS1302(); //时钟芯片初始化

    up_flag=0;

    down_flag=0;

    done=0;           //进入默认液晶显示

    while(1)

    {   while(done==1) keydone();    //进入调整模式

        while(done==0)

        {   show_time();                //液晶显示数据

            flag=0;                  Setkey();              //扫描各功能键

        }}}



客服QQ:496889925   电话15831080855
冀ICP备11001230号
Powered by OTCMS V2.3