找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2725|回复: 7
打印 上一主题 下一主题
收起左侧

12864万年历新款PCB

[复制链接]
跳转到指定楼层
楼主
话不多说自己看
QQ同V:1137035271

#include <reg52.h>
#include <intrins.h>
#include "LCD12864.h"
#include "DS1302.h"
#include "DS18B20.h"
#include "nongli.h"
#include "displaytime.h"
#include "zk.h"
#include "bell.h"
#include "HW.H"
#include "delay.h"

#define uint  unsigned int
#define uchar unsigned char

/*--------------------定义按键-----------------------------------------------*/
sbit K1  = P2^1; //K1-设置
sbit K2  = P2^0; //K2-确认、返回
sbit K3  = P3^7; //K3-加
sbit K4  = P3^6; //K4-减
//K5=P1^4,K5-控制闹钟的打开与关闭,在"hw.h"中定义

/*---------------------函数声明------------------------------*/             
void ds_w0(void);
void ds_w(void);
void Conver_week(bit c,uchar year,uchar month,uchar day);
/*-----------------------------定义全局变量------------------------------*/
bit  w=0;    //调时标志位

unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)
signed char address,item,item0,max,mini;
unsigned char clk_ala[2]={0x00,0x00};//闹钟数据存放初,始值为00:00
unsigned char hour,minute,time;//用于闹铃的设置



/*-----------------------------日期、时间设置函数-----------------------------*/

void tiaozheng(void){
        yy = read_clock(0x8d);//调用1302时钟数据中的年数据,从地址0x8d中
        mo = read_clock(0x89);//调用1302时钟数据中的月数据,从地址0x89中
        dd = read_clock(0x87);//从1302芯片中读取日数据,从地址0x87中
        week = read_clock(0x8b);//从1302芯片中读取星期数据,从地址0x8b中
        //----------------------------------
        lcm_w_test(0,0x80);
        lcm_w_word("20");//显示内容字符20
        lcm_w_test(1,(yy/16)+0x30);//函数参数1,代表本行写数据,YY/16+0X30得出年十位数字的显示码地址,送显示       
        lcm_w_test(1,yy%16+0x30);//函数
        lcm_w_word("年");
        //----------------------------------
        lcm_w_test(1,(mo/16)+0x30);
        lcm_w_test(1,mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示
        lcm_w_word("月");//调用字符显示函数,显示文字 月
        //----------------------------------
/*
        lcm_w_test(0,0x88);//第一个参数0,表示本行写入LCM的是指令,指定显示位置88H(第三行左端)
        lcm_w_word("星期");//调用字符显示函数,显示文字 星期
        lcm_w_test(1,mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示
*/
        //----------------------------------
        lcm_w_test(1,(dd/16)+0x30);
        lcm_w_test(1,dd%16+0x30);//第一个1参数,表示本行写数据,日数据与16取余得个位数,加0x30得到显示码
        lcm_w_word("日");//显示字符 日
        //----------------------------------
        if(read_clock(0x85) != hh){//如果程序中的小时与1302芯片中的不同,
                hh = read_clock(0x85);//刷新程序中的小时数据
        }
        lcm_w_test(0,0x91);//第一个参数0,表示本行写入LCM的是指令,指定显示位置88H(第三行左端)
        lcm_w_test(1,(hh/16)+0x30);//显示十位
        lcm_w_test(1,hh%16+0x30);//显示个位
        lcm_w_word("时");
        //----------------------------------
        if(read_clock(0x83) != mm){//如果1302芯片中的分钟数据与程序中的分钟变量不相等               
                mm = read_clock(0x83);//刷新程序中的分钟数据
        }
        lcm_w_test(1,(mm/16)+0x30);//向液晶写数据,显示分钟的十位数
        lcm_w_test(1,mm%16+0x30);//向液晶写数据,显示分钟的个位数
        lcm_w_word("分");
        //----------------------------------
        if(read_clock(0x81) != ss){//如果1302芯片中的分钟数据与程序中的秒钟变量不相等(0x81为读秒数据0x80为写秒数据)               
                ss = read_clock(0x81);//刷新程序中的秒钟数据
        }
        lcm_w_test(1,(ss/16)+0x30);//向液晶写数据,显示分钟的十位数
        lcm_w_test(1,ss%16+0x30);//向液晶写数据,显示分钟的个位数
        lcm_w_word("秒");

//////////////////////////////////////////////////////////////////////
        //=========显示闹钟的设置时间===================       
       
        hour=clk_ala[0];        //取出上一次的闹钟小时值
        minute=clk_ala[1];         //取出上一次的闹钟分钟值
       
        lcm_w_test(0,0x88);
        lcm_w_word("闹钟---");
        //----------------------------       
        lcm_w_test(1,(hour/10)+0x30);//显示小时十位
        lcm_w_test(1,(hour%10)+0x30);//显示小时个位
        //----------------------------
          lcm_w_word(":");
        //----------------------------
        lcm_w_test(1,(minute/10)+0x30);//显示分钟的十位
        lcm_w_test(1,(minute%10)+0x30);//显示分钟的个位
        //----------------------------
        lcm_w_word("----");


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

}
/*****************************************************************************/
//被调数据加一或减一,并检查数据范围,写入1302指定地址保存
void ds_w(void)
{
        item0=time;
        item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;//时间的调整
        if(K3 == 0||key_add==1){//如果按动上调键
         item++;//数加 1  
        }
        if(K4 == 0||key_minish==1){//如果按动下调键
           item--;//数减 1
        }
        if(item>max)  item=mini;//查看数值是否在有效范围之内   
        if(item<mini) item=max;//如果数值小于最小值,则自动等于最大值           
        write_clock(0x8e,0x00);//允许写1302芯片操作
        write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302
        write_clock(0x8e,0x80);//写保护,禁止写操作
}

/********************************************************************/
//===============闹钟时间的加减设置======================
void ds_w0(void)
{
  item0=time;

  if(K3 == 0||key_add==1){//如果按动上调键
        item0++;//数加 1
        }
  if(K4 == 0||key_minish==1){//如果按动下调键
        item0--;//数减 1
        }
  if(item0>max) item0=mini;//查看数值是否在有效范围之内
  if(item0<mini)item0=max;//如果数值小于最小值,则自动等于最大值
  time=item0;//调整后的时间重新赋值给time(time为hour或minute),这步很重要,没有将无法更新闹钟数据
}


/**********************************************************************************************************/
//调整时间子函数,设置键、数据范围、上调加一,下调减一功能。
void Set_time(unsigned char sel){ //根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数

        write_com(0x30); write_com(0x06);

        lcm_w_test(0,0x98);//第一参数0表示本行写入指令,指定下面行的 调整 显示起始位置为9AH
        lcm_w_word(">>调整>>    <<<<");//调用字符显示函数,显示 调整字样

/*        if(sel==8)  {lcm_w_word("星期");address=0x8a; max=7;mini=1;          
     tiaozheng();
     ds_w();
     tiaozheng();
          }
*/
//================================================================
        lcm_w_test(0,0x9c);
        if(sel==7)  {lcm_w_word("闹钟分"); time=minute;max=59;mini=0;        
         tiaozheng();//显示调整前的内容
     ds_w0();//设置闹钟
         clk_ala[1]=time;//把更新后的分钟数据重新保存
     tiaozheng();//显示调整后的内容
          }//按动8次显示 调整闹钟的分钟部分
        if(sel==6)  {lcm_w_word("闹钟时");time=hour; max=23;mini=0;
     tiaozheng();
     ds_w0();
         clk_ala[0]=time;//把更新后的小时数据重新保存
     tiaozheng();
          }//按动7次显示 调整闹钟的小时部分
//================================================================

        if(sel==5)  {lcm_w_word("秒钟");address=0x80; max=59;mini=0;          
        tiaozheng();  //调用日期、时间调整函数
           ds_w();                  //被调数据加一或减一函数
           tiaozheng();

        }        //秒6,按动6次显示 调整秒钟   
                //并指定秒钟数据写入1302芯片的写入地址是0x80,秒钟数据的最大值是59,最小值是0

        if(sel==4)  {lcm_w_word("分钟");address=0x82; max=59;mini=0;
           tiaozheng();
           ds_w();
           tiaozheng();

        }        //分钟5,按动5次显示 调整分钟
                //并指定分钟数据写入1302芯片的地址是0x82,分钟数据的最大值是59,最小值是0

        if(sel==3)  {lcm_w_word("小时");address=0x84; max=23;mini=0;

            tiaozheng();
           ds_w();
           tiaozheng();

        }        //小时4,按动4次显示 调整小时
                //规定小时数据写入1302芯片的位置是0x84,小时数据最大值23,最小值是0


        if(sel==2)  {lcm_w_word("日期");address=0x86;
                mo = read_clock(0x89);//读月数据
                moontemp1=mo/16;
                moontemp2=mo%16;
                mo=moontemp1*10+moontemp2;//转换成10进制月份数据

      yy = read_clock(0x8d);//读年数据
      moontemp1=yy/16;
                moontemp2=yy%16;
                yy=moontemp1*10+moontemp2;//转换成10进制年份数据

      if(mo==2&&yy%4!=0){max=28;mini=1;}//平年2月28天
                if(mo==2&&yy%4==0){max=29;mini=1;}//闰年2月29天
                if(mo==1||mo==3||mo==5||mo==7||mo==8||mo==10||mo==12){max=31;mini=1;}//31天的月份
                if(mo==4||mo==6||mo==9||mo==11){max=30;mini=1;}//30天的月份
                tiaozheng();
                ds_w();
                tiaozheng(); //调用日期、时间调整函数

  }        //日3,按动3次显示 调整日期
                //规定日期数据写入1302的位置地址是0x86,日期最大值31,最小值是1



  if(sel==1)  {lcm_w_word("月份");address=0x88; max=12;mini=1;
     tiaozheng();
     ds_w();
     tiaozheng();

   }        //月2,按动2次显示 调整月份
                //规定月份写入1302的位置地址是0x88,月份最大值12,最小值1


  if(sel==0)  {lcm_w_word("年份");address=0x8c; max=99; mini=0;
         tiaozheng();
     ds_w();                //被调数据加一或减一函数
     tiaozheng();        //调用日期、时间调整函数

   }        //年1,按动1次显示 调整年份,
                //规定年份写入1302的地址是0x8c,年份的最大值99,最小值0

}

/*********************************************************************
**********************************************************************
**************             主函数                                  ****************
**********************************************************************
/********************************************************************/
void main()
{       
        unsigned char e=0,f=0,tmp,i;                     

    IE = 0x81;    //允许总中断中断,使能 INT0 外部中断
    TCON = 0x01;  //触发方式为脉冲负边沿触发   
    IRIN=1;       //IO口初始化
    BEEP=1;
        K1=1;K2=1;K3=1;K4=1;
       
       
        Init_1302();                //时钟芯片初始化
        lcm_init();                        //液晶初始化
        welcome0();  //调用欢迎信息1
        DelayM(2000);//延时
        //welcome();DelayM(1000);  //调用欢迎信息2                
        lcm_clr();            //清屏
        Clean_12864_GDRAM();         //清屏
        while(1)
        {


                if (w == 0)                  //正常走时
                {
                        displaydate();         //显示日期
                        displaynl();         //显示农历
                        displaytime();         //显示时间
                        read_temp();         //读取温度
                        ds1820disp();          //显示温度
                        displayxq();         //显示星期
                               
                //=================以下是闹钟的相关处理===================
                       
                        if(ala_flag==1){//闹钟标志位               
                        set1616pic(6,1,0,2);} //显示"闹钟图标"               
                    else{                                                                               
                        set1616pic(6,1,0,3);}//关闭"闹钟图标"显示

                        //----------------------------------------
                        tmp=read_clock(0x85);//取出1302小时
                        i = tmp/16;
                        tmp = tmp&0x0f;
                        tmp = tmp + i*10;
                        if(clk_ala[0]==tmp)//与闹钟设定的小时值相同
                                {
                                tmp=read_clock(0x83);//取出1302分钟
                                i = tmp/16;
                                tmp = tmp&0x0f;
                                tmp = tmp + i*10;
                                        if(clk_ala[1]==tmp)//与闹钟设定的分钟值相同
                                          {
                                                if(ala_flag==1)//闹钟打开
                                                  {
                                                        alarmbeep();//闹铃声响1分钟后自动关闭,
                                                        DelayM(200);//控制闹钟响的间隔即频率
                                                   }
                                                else BEEP=1;//关闭蜂鸣器
                                           }
                                         else BEEP=1;//关闭蜂鸣器
                                }
                        //==============闹钟处理结束=======================
                }       
                else {} //========否则启动调时=========================


/*---------------按键及红外遥控设置时间------------------------------*/               
                if (K1 == 0||key_manue==1)         
                {                 
                       
                        DelayM(8);                       //按键消抖
/*当是调时状态 本键用于调整下一项---------------------------------------------------*/               
                        if((K1 == 0 && w == 1)||(key_manue==1&&w==1))      //
                        {
                                       
                                e++;
                                if (e >= 8 ) {e = 0;}
                             while(! K1 );            //等待键松开
                          key_manue=0;
                                Set_time(e); beep();          //调整                               
                        }
/*当是正常状态时就进入调时状态---------------------------------------------------*/               
                        if((K1 == 0 && w == 0)||(key_manue==1&&w==0))  //
                        {       
                                key_manue=0;
                                lcm_clr();            
                                Clean_12864_GDRAM();   //清屏
                                w=1;                       //进入调时
                                Set_time(e);beep();
                        }
                           while(K1 == 0);            //等待键松开
                }
/*当在调时状态时就退出调时---------------------------------------------------*/               
                if (K2 == 0||key_ok==1)                   //
                {        beep();
                        DelayM(8);
                        if((K2 == 0 && w == 1)||(key_ok==1&&w==1))
                        {                       
                                w = 0;                       //退出调时
                                e = 0;                           //"下一项"计数器清0                                                               
                        }
                        if((K2 == 0 && w == 0)||(key_ok==1&&w==0))
                        {
                                lcm_clr(); Clean_12864_GDRAM();
                                write_com(0x30); write_com(0x06);
                                welcome();       
                                while(K2 == 0); //按下K2是显示欢迎信息
                                DelayM(500);key_ok=0;//红外"OK"按键按下时显示0.5秒钟的欢迎界面2                                 
                        }
                        lcm_clr(); Clean_12864_GDRAM();
//                        ds_write(0x0a,0x20);       //调时完毕,开启时钟振荡器                               
                        displaydate();
                        displayxq();
                        displaynl();
                        displaytime();
                        read_temp();
                        ds1820disp();
                        while(K2 == 0);  
                }
/*加调整--------------------------------------------------------------------*/               
                if ((K3 == 0 && w == 1)||(key_add==1&&w==1))
                {        
                         DelayM(8);
                        if((K3 == 0 && w == 1)||(key_add==1&&w==1))
                                {
                                  Set_time(e);
                                  beep();
                                  while(!K3);
                                  key_add=0;
                                }
                        key_add=0;
                        while(! K3 );
                }
/*减调整--------------------------------------------------------------------*/               
                if ((K4 == 0 && w == 1)||(key_minish==1&&w==1))
                {             
                        DelayM(10);          
                        if((K4 == 0 && w == 1)||(key_minish==1&&w==1))
                          {
                                Set_time(e);
                            beep();
                                while(! K4 );
                                key_minish=0;
                          }
                        key_minish=0;
                        while(! K4 );
                }
/*----------------------------------------------------------------*/

        }
}


IMG_3347.JPG (1.87 MB, 下载次数: 27)

IMG_3347.JPG
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:165792 发表于 2019-1-9 19:59 | 只看该作者
谢谢分享
回复

使用道具 举报

板凳
ID:471371 发表于 2019-1-21 18:25 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:79874 发表于 2019-1-23 09:25 | 只看该作者
设计的PCB
回复

使用道具 举报

5#
ID:79874 发表于 2019-1-23 10:05 | 只看该作者
能分享下压缩包吗
回复

使用道具 举报

6#
ID:471770 发表于 2019-1-23 14:51 | 只看该作者

谢谢分享
回复

使用道具 举报

7#
ID:3802 发表于 2019-1-23 15:05 | 只看该作者
谢谢分享
回复

使用道具 举报

8#
ID:564898 发表于 2019-6-17 23:48 | 只看该作者
谢谢,正在找大字体万年历
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表