DS1302.c

#include "DS1302.h"
#include "lcd1602.h"//引脚定义
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;//寄存器写入地址/指令定义
#define DS1302_miao     0x80
#define DS1302_feng     0x82
#define DS1302_shi          0x84
#define DS1302_ri           0x86
#define DS1302_yue      0x88
#define DS1302_xingqi           0x8A
#define DS1302_nian         0x8C
#define DS1302_WP           0x8E       //写保护//时间数组,索引0~6分别为年、月、日、时、分、秒、星期,设置为有符号的便于<0的判断
char  DS1302_Time[]={19,11,16,22,56,0,6};void DS1302_Init(void)  //DS1302初始化
{DS1302_CE=0;DS1302_SCLK=0;
}void DS1302_WriteByte(unsigned char Command,Data) //DS1302写一个字节 Command 命令字/地址 Data 要写入的数据
{unsigned char i;DS1302_CE=1;                    //CE时钟高开始写数据for(i=0;i<8;i++)                //写命令{//      DS1302_IO=Command&(0x01<<i);  //最低位开始写DS1302_IO=Command&0x01;    //读数据Command >>= 1;DS1302_SCLK=1;               //SCLK高写数据DS1302_SCLK=0;}for(i=0;i<8;i++)              //写数据{DS1302_IO=Data&(0x01<<i);   //最低位开始写
//     DS1302_IO=Data&0x01;    //读数据
//     Data >>= 1;DS1302_SCLK=1;             //SCLK高写数据DS1302_SCLK=0; }DS1302_CE=0;                //写完释放时钟CE置零
}unsigned char DS1302_ReadByte(unsigned char Command)  //DS1302读一个字节 Command 命令字/地址
{unsigned char i,Data=0x00;Command|=0x01; //将指令转换为读指令DS1302_CE=1;       //CE时钟高开始读数据afor(i=0;i<8;i++)               //读命令{DS1302_IO=Command&(0x01<<i);    //读数据
//    DS1302_IO=Command&0x01;    //读数据
//    Command >>= 1;DS1302_SCLK=0;DS1302_SCLK=1;  //SCLK高写数据}for(i=0;i<8;i++)    //读数据{DS1302_SCLK=1;   DS1302_SCLK=0;     //SCLK读数据if(DS1302_IO){Data|=(0x01<<i);} //{Data=Data|(0x01<<i);}  读出端口是1就置1
//     Data>>=1;
//    if(DS1302_IO){Data|=0x80;} //{Data=Data|(0x01<<i);}  读出端口是1就置1}DS1302_CE=0;       //读完释放时钟CE置零DS1302_IO=0;  //读取后将IO设置为0,否则读出的数据会出错return Data;}uchar dat_to_BCD(uchar dat)//数据转BCD码
{uchar dat1,dat2;dat1 = dat / 10;dat2 = dat % 10;dat2 = dat2 + dat1 * 16;return dat2;
}uchar BDD_to_dat(uchar dat)//BCD码转数据
{uchar dat1,dat2;dat1 = dat /16;dat2 = dat % 16;dat2 = dat2 + dat1 * 10;return dat2;
}void DS1302_SetTime(void)  //十进制转BCD码后写入DS1302中
{DS1302_WriteByte(DS1302_WP,0x00);  //WP=0 写操作DS1302_WriteByte(DS1302_nian,dat_to_BCD(DS1302_Time[0]));//年DS1302_WriteByte(DS1302_yue,dat_to_BCD(DS1302_Time[1])); //月DS1302_WriteByte(DS1302_ri   ,dat_to_BCD(DS1302_Time[2]));//日DS1302_WriteByte(DS1302_shi ,dat_to_BCD(DS1302_Time[3]));//时DS1302_WriteByte(DS1302_feng,dat_to_BCD(DS1302_Time[4]));//分DS1302_WriteByte(DS1302_miao,dat_to_BCD(DS1302_Time[5]));//秒DS1302_WriteByte(DS1302_xingqi,dat_to_BCD(DS1302_Time[6]));//星期DS1302_WriteByte(DS1302_WP,0x80);    //WP=0x80打开写保护功能}void DS1302_ReadTime(void)  //BCD码转十进制后保存到数组准备读取
{DS1302_Time[0]=BDD_to_dat(DS1302_ReadByte(DS1302_nian));DS1302_Time[1]=BDD_to_dat(DS1302_ReadByte(DS1302_yue));DS1302_Time[2]=BDD_to_dat(DS1302_ReadByte(DS1302_ri));DS1302_Time[3]=BDD_to_dat(DS1302_ReadByte(DS1302_shi));DS1302_Time[4]=BDD_to_dat(DS1302_ReadByte(DS1302_feng));DS1302_Time[5]=BDD_to_dat(DS1302_ReadByte(DS1302_miao));DS1302_Time[6]=BDD_to_dat(DS1302_ReadByte(DS1302_xingqi));
}void TimeShow(void)//时间显示功能
{DS1302_ReadTime();//读取时间LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒
}

DS1302.h

#include "system.h"//外部可调用时间数组,索引0~6分别为年、月、日、时、分、秒、星期,设置为有符号的便于<0的判断
extern char DS1302_Time[];void DS1302_Init(void);
void DS1302_WriteByte(unsigned char Command,Data);
unsigned char DS1302_ReadByte(unsigned char Command);
void DS1302_SetTime(void);
void DS1302_ReadTime(void);uchar dat_to_BCD(uchar dat);//数据转BCD码
uchar BDD_to_dat(uchar dat);//BCD码转数据void TimeShow(void);//时间显示功能;#endif

key.c

#include "key.h"    //把led.h文件包含进来
#include "system.h"      //把timer0.h文件包含进来
#include "led.h"#include "DS1302.h"
#include "lcd1602.h"
uchar p=0;unsigned char TimeSetSelect;
uchar flag,wei;    //在其他模块中寻找其定义。另外,extern也可用来进行链接指定。u8 KeyScan ()       //按键扫描函数
{static uint timer=0;if(k1==0){  timer++;if(timer==10){return 1;} //定时10毫秒返回else if(timer==1000){timer=500;return 1;} //否则长按不停加1}else if(k2==0){timer++;  if(timer==10){return 2;} //定时10毫秒返回//else if(timer==1000){timer=900;return 2;} //否则长按不停加1else if(timer==1000){timer=500;return 2;} //否则长按不停加1}else if(k3==0){timer++;if(timer==10){return 3;} //定时10毫秒返回else if(timer==1000){timer=500;return 3;} //否则长按不停加1}else if(k4==0){timer++;if(timer==10){return 4;}  //定时10毫秒返回else if(timer==1000){timer=500;return 4;} //否则长按不停加1}else{timer=0;      //定时清0}return 0;
}void datapros()
{uchar key;key=KeyScan();   //key=调用检测按键函数if(key==1)       {p++;if(p>1){p=0;}
//     p%=2;//越界清零
//     p=p%2;//越界清零}if(flag==1)  //加了我之后,我的大括号里面的东西,被定期的1ms执行一次,反复执行        {lcd_sansuo();  //lcd选中的位闪烁if(key==2){wei++;//设置选择位加1wei%=6;//位选越界清零LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒                 }if(key==3){switch(wei)   //选中的位选--{case 0:  DS1302_Time[0]++; break;  //年++case 1:  DS1302_Time[1]++; break;  //月++case 2:  DS1302_Time[2]++; break;  //日++case 3:  DS1302_Time[3]++; break;  //时++case 4:  DS1302_Time[4]++; break;  //分++case 5:  DS1302_Time[5]++; break;  //秒++} if(DS1302_Time[0]>99){DS1302_Time[0]=0;}//年越界判断if(DS1302_Time[1]>12){DS1302_Time[1]=1;}//月越界判断if(DS1302_Time[2]>12){DS1302_Time[2]=0;}//日越界判断if(DS1302_Time[3]>23){DS1302_Time[3]=0;}//时越界判断if(DS1302_Time[4]>59){DS1302_Time[4]=0;}//分越界判断if(DS1302_Time[5]>59){DS1302_Time[5]=0;}//秒越界判断LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒                    DS1302_SetTime(); //十进制转BCD码后写入}if(key==4){switch(wei)    //选中的位选--{case 0:  DS1302_Time[0]--; break;  //年++case 1:  DS1302_Time[1]--; break;  //月++case 2:  DS1302_Time[2]--; break;  //日++case 3:  DS1302_Time[3]--; break;  //时++case 4:  DS1302_Time[4]--; break;  //分++case 5:  DS1302_Time[5]--; break;  //秒++} if(DS1302_Time[0]<0){DS1302_Time[0]=99;}//年越界判断if(DS1302_Time[1]<1){DS1302_Time[1]=12;}//月越界判断if(DS1302_Time[2]<0){DS1302_Time[2]=31;}//时越界判断if(DS1302_Time[3]<0){DS1302_Time[3]=23;}//时越界判断if(DS1302_Time[4]<0){DS1302_Time[4]=59;}//分越界判断if(DS1302_Time[5]<0){DS1302_Time[5]=59;}//秒越界判断LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒                    DS1302_SetTime(); //十进制转BCD码后写入}}
}void moshi()  //模式切换
{//  uchar key;
//  key=KeyScan();  //key=调用检测按键函数//  if(key==1)
//   {//   p++;//    if(p>1){p=0;}
////     p%=2;//越界清零
////     p=p%2;//越界清零
//   }switch(p){case 0: TimeShow();flag=0; break;//时间显示功能  case 1:;flag=1;break;    }
}void lcd_sansuo()
{static uint i;i++;if(i==500)//500ms{  switch(wei)     //选中的位选{case 0:  LCD_ShowString(1,1,"  "); break;  //年++case 1:  LCD_ShowString(1,4,"  "); break;  //月++case 2:  LCD_ShowString(1,7,"  "); break;  //日++case 3:  LCD_ShowString(2,1,"  "); break;  //时++case 4:  LCD_ShowString(2,4,"  "); break;  //分++case 5:  LCD_ShowString(2,7,"  "); break;  //秒++}    }if(i==1000)   //1000ms{i=0;switch(wei)   //选中的位选{case 0:  LCD_ShowNum(1,1,DS1302_Time[0],2); break;  //年++case 1:  LCD_ShowNum(1,4,DS1302_Time[1],2); break;  //月++case 2:  LCD_ShowNum(1,7,DS1302_Time[2],2); break;  //日++case 3:  LCD_ShowNum(2,1,DS1302_Time[3],2); break;  //时++case 4:  LCD_ShowNum(2,4,DS1302_Time[4],2); break;  //分++case 5:  LCD_ShowNum(2,7,DS1302_Time[5],2); break;  //秒++}            }}

key.h

#include "system.h"       //把timer0.h文件包含进来sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;   //定义按键端口u8 KeyScan ();     //按键扫描函数
void datapros();void moshill();    //模式切换
void lcd_sansuo(); //lcd选中的位闪烁

main.c

#include "system.h"
#include "key.h"
#include "led.h"
#include "lcd1602.h"
#include "system.h"
#include "DS1302.h"extern uchar flag_1ms;    //在其他模块中寻找其定义。另外,extern也可用来进行链接指定。void main(void)         //程序的主函数
{Timer0_Init(); ////定时器0函数调用LCD_Init();DS1302_Init();LCD_ShowString(1,1,"  -  -  ");//静态字符初始化显示LCD_ShowString(2,1,"  :  :  ");DS1302_SetTime();//设置时间while(1)           //大括号里面的东西,被不停的循环执行{ //1ms进入一次if(flag_1ms==1)  //加了我之后,我的大括号里面的东西,被定期的1ms执行一次,反复执行        {flag_1ms=0;moshi(); //    时钟模式切换}}
}

system.h

#include "reg51.h"#define  uchar unsigned char //定义无符号字符
#define uint  unsigned int  //定义无符号整形#define    u8 unsigned char    //定义无符号字符
#define u16  unsigned int   //定义无符号整形#define    FOSC    12000000L   //定义晶振频率
#define T1MS    (65536-FOSC/12/1000)  //定时1毫秒的时候,计数器要写入的值void    Delay_us(uint xus); //us级延时
void    Delay_ms(uint xms); //ms级延时
void    Timer0_Init(void);      //定时器初始化

system.c

#include "system.h"uchar flag_1ms=0;void  Timer0_Init(void)
{TH0 = T1MS>>8; //赋初值TL0 = T1MS;       //赋初值TMOD = 0x01;  //设置定时器0用十六位定时器方式EA = 1;             //打开总中断ET0 = 1;        //打开定时器0中断TR0 = 1;         //启动定时器0
}void Timer0() interrupt 1       //中断号1
{   TH0 = T1MS>>8; //赋初值TL0 = T1MS;    //赋初值flag_1ms=1;datapros();}void    Delay_us(uint xus)
{for(;xus>0;xus--);
}void   Delay_ms(uint xms)
{for(;xms>0;xms--){Delay_us(1000);}
}

51_LCD1602 - DS1302可调时钟相关推荐

  1. 【DS1302可调时钟】

    DS1302可调时钟 0.原理图 1.DS1302介绍 2.引脚定义与应用电路 3.内部结构框图 4.寄存器定义 5.时序定义 6.BCD码 7.源码 ==main.c== ==DS1302.c== ...

  2. 51单片机——DS1302可调时钟

    目录 一.功能介绍 二.主要模块介绍 2.1 DS1302模块 2.1.1 DS1302芯片介绍 2.1.2  DS1302的使用 三.程序汇总 3.1测试文件test.c 3.2 LCD1602模块 ...

  3. DS1302可调时钟

    文章目录 前言 模块划分 模块化编程 1. Key 2. LCD1602 3. Timer0 4. Delay 5. DS1302 6. Main 总结 前言 上节 " DS1302详解 & ...

  4. 51单片机---一起来学习DS1302可调时钟(stc89c52芯片)

    DS1302是一个实时时钟芯片,带有一个备用电池,在单片机不工作的时候继续走时:单片机 自带的定时器时钟并不能够调电继续运行,不能断电,然而这个时钟芯片带有备用电池,会给1302继续提供电流.(在主电 ...

  5. 51_数码管 - DS1302可调时钟

    DS1302.c #include "DS1302.h"//引脚定义 sbit DS1302_SCLK=P3^6; sbit DS1302_IO=P3^4; sbit DS1302 ...

  6. 51单片机-DS1302可调时钟(实现代码)

    目录 一.介绍 1.DS1302介绍 2.引脚定义和应用电路 3.内部结构框图 4. 寄存器定义 5.时序定义 6.BCD码 二.文件内容 a.代码功能 1.代码实现功能 2.工程文件内容 b.代码详 ...

  7. 51单片机_10-2 DS1302可调时钟

    文章目录 要求 效果 资源 main函数 要求 1.设置DS1302时钟芯片时间 2.读取DS1302时钟芯片时间并显示在LCD1602上 3.通过独立按键可修改当前时间,在修改模式中,对选中的属性进 ...

  8. 51DS1302时钟及可调时钟(完整代码)

    DS1302时钟 #include <REGX52.H> #include "LCD1602.h" #include "DS1302.h" void ...

  9. 51单片机进阶案例(1)——基于MATLAB GUI的单片机串口与PC的通信实现实时时钟和双向可调时钟功能(利用DS1302时钟芯片和LCD1602液晶屏)

    目录 一.案例描述 二.实现功能 三.51单片机部分实现 3.1 实时时钟的实现 3.2 串口通信的实现 3.2.1 接收数据 3.2.2 发送数据 四.MATLAB部分实现 4.1 GUI界面 4. ...

最新文章

  1. idea(3)-jetty配置
  2. sys.argv[]学习
  3. EDM营销之如何使邮件列表更加有效
  4. php中的数组用什么统计,php数组元素统计与值汇总
  5. 频率单位Hz、MHz、GHz、THz、PHz、EHz换算关系
  6. AltRun调用cmd并刷新DNS
  7. VMware中创建虚拟机并安装Linux操作系统教程
  8. 单片机需要数电模电基础吗?单片机要多少模电数电知识 ?
  9. LINUX重新编译BIN固件,固件编译
  10. gerrit常见错误与处理
  11. 变量消元(Varible Elimination)和概率边缘化(Marginalization)的关系
  12. java学习笔记(10) 第10 章(上) - 面向对象编程(高级部分)
  13. div显示在上层_html如何将一个div置于最上层
  14. 最全的硬盘修复专题帖(转贴)
  15. 华为OD机试 - 玩牌高手(Python) | 机试题算法+思路 【2023】
  16. Python打包出现 failed to execute script xxx解决方法
  17. python获取内存地址上存储的值
  18. Hadoop-2.5.2集群安装配置详解
  19. Unity GC问题刨析1--结构体
  20. Cocos2dx 2.x 适配最新XCode 12

热门文章

  1. php实训表单验证的日记心得,php实训心得
  2. C++ 虚函数详解(虚函数表、vfptr)——带虚函数表的内存分布图
  3. 手游堡垒之夜服务器没响应,堡垒之夜国际服点启动没反应 | 手游网游页游攻略大全...
  4. 2055 到淄博旅游
  5. 外卖商品的标准化建设与应用
  6. 中国智慧生活博览会(CEE 2017)—数字世界亚洲博览会会刊(参展商名录)
  7. java基础案例4-2饲养员喂养动物
  8. xp系统禁用wmi服务器,xp中哪些服务是可以关闭的
  9. 网友晒“老妈口头禅” 引集体共鸣
  10. 前端linux基础,这一篇就够了