找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC89C52+LCD12864+DS1302+DS18B20时钟原理图+源程序

  [复制链接]
跳转到指定楼层
楼主
STC89C52+LCD12864+DS1302 +DS18B20时钟供大家学习。

            电子智能时钟程序
            单 片 机:STC89C52
     晶    振:12MHz
         时钟芯片:DS1302
            液 晶 屏:LCD12864

                时    间:2020年1月1日
                LCD12864使用并口连接方式,PSB、RST接高电平




/*-------------------------------头文件---------------------------------------*/

#include <reg52.h>

#include <intrins.h>

#include "LCD12864.h"

#include "DS1302.h"

#include "DS18B20.h"

#include "nongli.h"

#include "displaytime.h"

//#include "jieqi.h"

#define uint  unsigned int

#define uchar unsigned char


/*----------------------------定义按键---------------------------------------*/

sbit K1  = P2^3; //K1-设置  

sbit K2  = P2^2; //K2-确认、返回   

sbit K3  = P2^1; //K3-加         

sbit K4  = P2^0; //K4-减         

//sbit K5  = P3^7; //液晶背光控制按键,按一下亮,再按一下灭                 

//sbit BLK = P3^7; //液晶背光控制输出,低电平有效,PNP三极管控制。


/*---------------------函数声明------------------------------*/

void DelayM(uint);               

void ds_w(void);

void Conver_week(bit c,uchar year,uchar month,uchar day);

/*-----------------------------定义全局变量------------------------------*/

bit q=0, w=0;    //调时标志位

unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)

signed char address,item,max,mini;


/*-----------------------------延时函数 1MS/次-------------------------------*/

void DelayM(uint a)               

{

        uchar i;

        while( --a != 0) { for(i = 0; i < 125; i++); }                                      

}

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


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

        write_data(yy/16+0x30);//函数参数1,代表本行写数据,YY/16+0X30得出年十位数字的显示码地址,送显示        

        write_data(yy%16+0x30);//函数?

        lcm_w_word("年");


        write_data(mo/16+0x30);

        write_data(mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示

        lcm_w_word("月");     //调用字符显示函数,显示文字 月   


        write_data(dd/16+0x30);

        write_data(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的是指令,指定显示位置91H(第三行左端)

        write_data(hh/16+0x30);  //显示十位



        write_data(hh%16+0x30);  //显示个位

        lcm_w_word("时");


        if(read_clock(0x83) != mm){//如果1302芯片中的分钟数据与程序中的分钟变量不相等               

                mm = read_clock(0x83);//刷新程序中的分钟数据

        }

        write_data(mm/16+0x30);//向液晶写数据,显示分钟的十位数

        write_data(mm%16+0x30);//向液晶写数据,显示分钟的个位数

        lcm_w_word("分");


        if(read_clock(0x81) != ss){//如果1302芯片中的分钟数据与程序中的秒钟变量不相等               

                ss = read_clock(0x81);//刷新程序中的秒钟数据

        }

        write_data(ss/16+0x30);//向液晶写数据,显示分钟的十位数

        write_data(ss%16+0x30);//向液晶写数据,显示分钟的个位数

        lcm_w_word("秒");         


}


/**********************************************************************************************************/

//调整时间子函数,设置键、数据范围、上调加一,下调减一功能。

void Set_time(unsigned char sel){ //根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数


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


        lcm_w_test(0,0x98);//第一参数0表示本行写入指令,指定下面行的 调整 显示起始位置为98H

        lcm_w_word("★调整");//调用字符显示函数,显示 调整字样


/*        if(sel==6)  {lcm_w_word("星期");address=0x8a; max=7;mini=1;         

     tiaozheng();

     ds_w();

     tiaozheng();

          }

*/

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

        if(sel==5)  {lcm_w_word("秒钟");address=0x80; max=59;mini=0;         

                tiaozheng();  //调用日期、时间调整函数

           ds_w();                  //被调数据加一或减一函数

           tiaozheng();



        }        //秒7,按动7次显示 调整秒钟   

                //并指定秒钟数据写入1302芯片的地址是0x82,秒钟数据的最大值是59,最小值是0

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

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

           tiaozheng();

           ds_w();

           tiaozheng();


        }        //分钟6,按动6次显示 调整分钟

                //并指定分钟数据写入1302芯片的地址是0x82,分钟数据的最大值是59,最小值是0



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

        /***********************************************************/

                 if(address > 12){

                                           address = address-12;        }

         /********************************************************/

            tiaozheng();

           ds_w();

           tiaozheng();


        }        //小时5,按动5次显示 调整小时

                //规定小时数据写入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


}


/*****************************************************************************/

//被调数据加一或减一,并检查数据范围,写入1302指定地址保存

void ds_w(void){


        item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;

        if(K3 == 0){ //如果按动上调键

                item++;  //数加 1  

        }                                                                                                                 

        if(K4 == 0){  //如果按动下调键

                  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 main()

{                             

        uchar e=0;

        K1=1;K2=1;K3=1;K4=1;//BLK=0;//K5=1;


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

        lcm_init();                        //液晶初始化

        welcome();                    //调用欢迎信息

        DelayM(4000);                 //欢迎信息 延时时间  

        lcm_clr();            //清屏

        Clean_12864_GDRAM();         //清屏

        while(1)

        {

                if (w == 0)                  //正常走时

                {

                        displaydate();         //显示日期

//                        displaynl();         //显示农历

                        nongli();                 //显示农历

//                        displayjieqi(); //显示节气

                        displaytime();         //显示时间

                        read_temp();         //读取温度

                        ds1820disp();          //显示温度

                        displayxq();         //显示星期

                }        

                else {}            //否则启动调时  


/*----------------------------设置时间--------------------------------------*/               

                if (K1 == 0)         

                {

                        DelayM(20);                       //按键消抖

                        if(K1 == 0 && w == 1)      //当是调时状态 本键用于调整下一项   

                        {

                                e++;

                                if (e >= 7 ) {e = 0;}

                           while(! K1 );            //等待键松开

                                Set_time(e);           //调整                                

                        }                        

                        if(K1 == 0 && w == 0)      //当是正常状态时就进入调时状态   

                        {

                                lcm_clr();            

                                Clean_12864_GDRAM();   //清屏

                                w=1;                       //进入调时

                                Set_time(e);

                        }

                           while(K1 == 0);            //等待键松开

                }

/*--------------------------------------------------------------------------*/               

                if (K2 == 0)                   // 当在调时状态时就退出调时

                {

                        DelayM(20);

                        if(K2 == 0 && w == 1)

                        {                                

                                w = 0;                       //退出调时

                                e = 0;                           //"下一项"计数器清0                                                               

                        }

                        if(K2 == 0 && w == 0)

                        {                                

                                lcm_clr(); Clean_12864_GDRAM();

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

                                welcome();                                

                                while(K2 == 0);  

                        }

                        lcm_clr(); Clean_12864_GDRAM();

                        displaydate();

                        displayxq();

                        displaynl();

                        displaytime();

                        read_temp();

                        ds1820disp();

                        while(K2 == 0);  

                }

/*加调整--------------------------------------------------------------------*/               

                if (K3 == 0 && w == 1)

                {

                        DelayM(20);

                        if(K3 == 0 && w == 1) { Set_time(e); }

                        while(K3 == 0);

                        while(! K3 );

                }

/*减调整--------------------------------------------------------------------*/               

                if (K4 == 0 && w == 1)

                {               

                        DelayM(20);

                        if(K4 == 0 && w == 1) { Set_time(e); }

                        while(K4 == 0);

                        while(! K4 );

                }

/*液晶背光控制,按一下亮,再按一下灭----------------------------------------*/

/*                if(K5 == 0)        

                {

                        DelayM(20); q = ~q;      //标志位取反

                         if(q){BLK = BLK | 1;}   

                                 else {BLK = BLK & 0;}   

                        while(K5 == 0);           

                }                          */

        }

}

/*结束----------------------------------------------------------------------*/



代码+pdf格式原理图.7z (194.38 KB, 下载次数: 357)

评分

参与人数 2黑币 +54 收起 理由
20768797 + 4 资料里没有pcb 只有原理图 pdf格式的2个 .
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:59151 发表于 2020-1-23 00:07 | 只看该作者
很好的资料,正在学习中,谢谢分享!
回复

使用道具 举报

板凳
ID:88256 发表于 2020-1-24 00:20 | 只看该作者
下载一个PCB图参考一下,谢谢了!
回复

使用道具 举报

地板
ID:88256 发表于 2020-1-24 00:23 | 只看该作者
下载的第二个附件里面并没有PCB图
回复

使用道具 举报

5#
ID:468209 发表于 2020-1-24 23:22 来自手机 | 只看该作者
非常感谢
回复

使用道具 举报

6#
ID:688109 发表于 2020-1-25 12:05 | 只看该作者
谢谢啦
回复

使用道具 举报

7#
ID:688109 发表于 2020-1-25 12:24 | 只看该作者
0谢谢
回复

使用道具 举报

8#
ID:60026 发表于 2020-2-8 18:57 | 只看该作者
很好的资料,谢谢分享!
回复

使用道具 举报

9#
ID:154109 发表于 2020-2-9 17:44 | 只看该作者
谢谢楼主,很好的资料,学习了
回复

使用道具 举报

10#
ID:418887 发表于 2020-2-17 20:20 | 只看该作者
不错,很好,最近需要
回复

使用道具 举报

11#
ID:535242 发表于 2020-2-18 15:10 | 只看该作者
找了几天了
回复

使用道具 举报

12#
ID:266164 发表于 2020-2-18 17:11 | 只看该作者
正在找这个资料,谢谢分享
回复

使用道具 举报

13#
ID:720241 发表于 2020-4-5 17:19 | 只看该作者
找了几天,这个能用
回复

使用道具 举报

14#
ID:966104 发表于 2021-10-3 23:54 | 只看该作者

很好的资料,正在学习中,谢谢分享!
回复

使用道具 举报

15#
ID:290578 发表于 2022-4-7 23:10 | 只看该作者
多谢分享,解决了我一直困扰的时序问题!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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