DS1302实现可调时钟

本代码以DS1302、定时器、独立按键、LCD1602实现了可调时钟。

原理图上的DS1302

按键在上一讲讲过了
LCD1602的代码以后再写

下面展示一些 内联代码片

main.c
#include<STC15F2K60S2.H>
#include "DS1302.h"
#include "LCD1602.h"
#include "Key.h"
#include "Timer0.h"//分别是键值 模式 时间类型设置选择 数据闪烁指示
unsigned char KeyNumber,Mode,TimeSetSelect,TimeSetFlag;/***  @brief        时间显示*  @param      无*  @retval        无*/
void TimeShow(void)
{//读取时间 把DS1302中的数据读取到DS1302_Time[]中 一直读取 一直更新DS1302_ReadTime();//把年月日时分秒显示到LCD1602上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);}
/***  @brief       时间设置*  @param      无*  @retval        无*/
void TimeSet()
{//如果键值为2 时间设置选择加一 最多到5if(KeyNumber==2){TimeSetSelect++;TimeSetSelect%=6;}//如果键值为3 时间设置选择对应的数据加一 如果溢出 专门设置下一个值if(KeyNumber==3){DS1302_Time[TimeSetSelect]++;if(DS1302_Time[0]>99){DS1302_Time[0]=0;}if(DS1302_Time[1]>12){DS1302_Time[1]=1;}if(DS1302_Time[1]==1||DS1302_Time[1]==3||DS1302_Time[1]==5||DS1302_Time[1]==7||DS1302_Time[1]==8||DS1302_Time[1]==10||DS1302_Time[1]==12){if(DS1302_Time[2]>31){DS1302_Time[2]=1;}}else if(DS1302_Time[1]==4||DS1302_Time[1]==6||DS1302_Time[1]==9||DS1302_Time[1]==11){if(DS1302_Time[2]>30){DS1302_Time[2]=1;}}else if(DS1302_Time[1]==2){if((DS1302_Time[0]%4==0)&&(DS1302_Time[0]%100!=0)){if(DS1302_Time[2]>29){DS1302_Time[2]=1;}}else{if(DS1302_Time[2]>28){DS1302_Time[2]=1;}//平年28天 闰年29天}}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;}}//如果键值为4 时间设置选择对应的数据减一 如果溢出 专门设置下一个值if(KeyNumber==4){DS1302_Time[TimeSetSelect]--;if(DS1302_Time[0]<0){DS1302_Time[0]=99;}if(DS1302_Time[1]<1){DS1302_Time[1]=12;}if(DS1302_Time[1]==1 || DS1302_Time[1]==3 || DS1302_Time[1]==5 || DS1302_Time[1]==7 || DS1302_Time[1]==8 || DS1302_Time[1]==10 || DS1302_Time[1]==12){ if(DS1302_Time[2]<1){DS1302_Time[2]=31;}if(DS1302_Time[2]>31){DS1302_Time[2]=1;}}else if(DS1302_Time[1]==4||DS1302_Time[1]==6||DS1302_Time[1]==9||DS1302_Time[1]==11){if(DS1302_Time[2]<1){DS1302_Time[2]=30;}if(DS1302_Time[2]>30){DS1302_Time[2]=1;}}if(DS1302_Time[1]==2){if((DS1302_Time[0]%4==0)&&(DS1302_Time[0]%100!=0)){if(DS1302_Time[2]<1){DS1302_Time[2]=29;}if(DS1302_Time[2]>29){DS1302_Time[2]=1;}}else{if(DS1302_Time[2]<1){DS1302_Time[2]=28;}//平年28天 闰年29天if(DS1302_Time[2]>28){DS1302_Time[2]=1;}//平年28天 闰年29天}}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;}}//如果选择到该项 且数据闪烁指示为一 则该位为空 否则显示正常数据if(TimeSetSelect==0&&TimeSetFlag==1){LCD_ShowString(1,1,"  ");}else{LCD_ShowNum(1,1,DS1302_Time[0],2);}if(TimeSetSelect==1&&TimeSetFlag==1){LCD_ShowString(1,4,"  ");}else{LCD_ShowNum(1,4,DS1302_Time[1],2);}if(TimeSetSelect==2&&TimeSetFlag==1){LCD_ShowString(1,7,"  ");}else{LCD_ShowNum(1,7,DS1302_Time[2],2);}if(TimeSetSelect==3&&TimeSetFlag==1){LCD_ShowString(2,1,"  ");}else{LCD_ShowNum(2,1,DS1302_Time[3],2);}if(TimeSetSelect==4&&TimeSetFlag==1){LCD_ShowString(2,4,"  ");}else{ LCD_ShowNum(2,4,DS1302_Time[4],2);}if(TimeSetSelect==5&&TimeSetFlag==1){LCD_ShowString(2,7,"  ");}else{ LCD_ShowNum(2,7,DS1302_Time[5],2);}}
void main()
{//初始化DS1302_Init();LCD_Init();Timer0Init();DS1302_SetTime();//符号LCD_ShowChar(1,3,'/');LCD_ShowChar(2,3,':');LCD_ShowChar(1,6,'/');LCD_ShowChar(2,6,':');while(1){ //返回键值KeyNumber=Key();//如果键值为一则改变模式Mode Mode的默认值为0 if(KeyNumber==1){if(Mode==0){Mode=1;}//Mode从1变为0时重新设置一遍时间else if(Mode==1){Mode=0;DS1302_SetTime();}} //Mode 0为显示时间模式 1为设置时间模式switch(Mode){case 0:TimeShow();break;case 1:TimeSet();break;}}
}
//定时器 0.5s闪烁指示值为1 下0.5s闪烁指示值为0
void Timer0_Routine() interrupt 1
{static unsigned int T0Count;//不是全局变量 是局部静态变量 退出之后还是会占据空间 不会释放 保留上一次的值TH0=0XFC;//65535/256TL0=0X18;//65535%256+1T0Count++;if(T0Count>=500){T0Count=0;TimeSetFlag=!TimeSetFlag;}
}

下面展示一些 内联代码片

DS1302.c
#include<STC15F2K60S2.H>//设置引脚
sbit DS1302_SCLK=P1^7;
sbit DS1302_IO=P2^3;
sbit DS1302_CE=P1^3;//设置寄存器地址
#define DS1302_SECOND           0X80
#define DS1302_MINUTE           0X82
#define DS1302_HOUR             0X84
#define DS1302_DATE             0X86
#define DS1302_MONTH            0X88
#define DS1302_DAY              0X8A
#define DS1302_YEAR               0X8C
#define DS1302_WP               0X8E//设置初始时间
unsigned char DS1302_Time[]={21,1,20,13,46,55,3};//2021/1/20 13:46:55 3/***  @brief       DS1302初始化*  @param     无*  @retval        无*/
void DS1302_Init(void)
{DS1302_CE=0;DS1302_SCLK=0;
}/***  @brief      通过指令给DS1302写数据*  @param        Command:指令选择寄存器地址*  @param     Data:数据*  @retval      无*/
void DS1302_WriteByte(unsigned char Command,Data)
{unsigned char i;DS1302_CE=1;//前八位写入命令for(i=0;i<8;i++){DS1302_IO=Command&(0x01<<i);DS1302_SCLK=1; DS1302_SCLK=0;}//后八位通过上升沿写入数据for(i=0;i<8;i++){DS1302_IO=Data&(0x01<<i);DS1302_SCLK=1; DS1302_SCLK=0;}DS1302_CE=0;//使能置零
}/***  @brief      读取数据*  @param      Command:指令选择寄存器地址*  @retval     返回读取到的存储在DS1302中的数据*/
unsigned char DS1302_ReadByte(unsigned char Command)
{unsigned char i,Data=0X00;Command|=0x01;DS1302_CE=1;//前八位写入命令for(i=0;i<8;i++){DS1302_IO=Command&(0x01<<i);DS1302_SCLK=0; DS1302_SCLK=1;} //后八位通过下降沿沿读取数据for(i=0;i<8;i++){DS1302_SCLK=1; DS1302_SCLK=0;if(DS1302_IO){Data|=(0X01<<i);}}DS1302_CE=0;//使能置零DS1302_IO=0;//IO口置零return Data;
}/***  @brief      设置时间*  @param      无*  @retval        无*/
void DS1302_SetTime(void)
{DS1302_WriteByte(DS1302_WP,0X00);//关闭写保护//DS1302_Time[]中的数据是十进制的,写入DS1302要转换成BCDDS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16+DS1302_Time[2]%10);DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16+DS1302_Time[6]%10);DS1302_WriteByte(DS1302_WP,0X80);//打开写保护
}/***  @brief      读取时间*  @param      无*  @retval        无*/
void DS1302_ReadTime(void)
{unsigned char Temp;//DS1302中的数据是BCD形式,读取到DS1302_Time[]要转换成十进制Temp=DS1302_ReadByte(DS1302_YEAR);DS1302_Time[0]=Temp/16*10+Temp%16;Temp=DS1302_ReadByte(DS1302_MONTH);DS1302_Time[1]=Temp/16*10+Temp%16;Temp=DS1302_ReadByte(DS1302_DATE);DS1302_Time[2]=Temp/16*10+Temp%16;Temp=DS1302_ReadByte(DS1302_HOUR);DS1302_Time[3]=Temp/16*10+Temp%16;Temp=DS1302_ReadByte(DS1302_MINUTE);DS1302_Time[4]=Temp/16*10+Temp%16;Temp=DS1302_ReadByte(DS1302_SECOND);DS1302_Time[5]=Temp/16*10+Temp%16;Temp=DS1302_ReadByte(DS1302_DAY);DS1302_Time[6]=Temp/16*10+Temp%16;
}

DS1302手册


代码说明

DS1302.c:
初始化函数void DS1302_Init(void):

将使能CE、时钟端SCLK置零

写数据函数void DS1302_WriteByte(unsigned char Command,Data)

先将使能端口打开。
写一个命令位之后时钟信号置1再置0,写完8位命令之后再同样的写8个数据位。

读数据函数unsigned char DS1302_ReadByte(unsigned char Command)

先定义一个将要传出去的数据变量Data=0x00,将使能端置零。
用上面同样的方法传入命令。
传出数据的时序就不一样了,先置1再置0再传数据,传8位数据。
将使能端和时钟端置零,输出。

设置时间函数void DS1302_SetTime(void)

打开写保护。
用写数据函数按时间项写入数据,这里是写入了我在DS1302.c定义的的时间,之后学了AD24C02可以实现数据存储,掉电不丢失。
最后关闭写保护。

读取时间函数void DS1302_ReadTime(void)

通过中间变量设置定义在DS1302.c的DS1302_Time[]。

main.c

初始化
一开始默认为显示时间模式,一开始显示的时间是在DS1302.c中的自定义的时间,然后都是用读取时间函数读取DS1302里面的时间(这个时间是随时间变化的)。
按一下S7之后进入设置时间模式,通过定时器,每500ms闪烁一下当前选中的时间项。
设置时间模式下按S6,时间项换成下一个,按S5该时间项+1,按S4该时间项-1,而且有边界。
再按一下S7,到显示时间模式,但是由于我们一直以来改变的都是DS1302.c中的数据,所以从设置时间模式到显示时间模式需要重新设置一下DS1302中的时间即用设置时间函数重新设置一遍时间。
其中关于DS1302中的BCD码的定义、与10进制的转换关系在单片机入门(三)----DS1302扩展----BCD码.

单片机入门(三)----DS1302时钟芯片 可调时钟相关推荐

  1. 单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》...

    引言 本设计以AT89S52单片机为控制核心,时钟芯片DS1302提供时钟源,配合LCD1602液晶显示模块,组成基本硬件系统,同时利用HC-05嵌入式蓝牙串口通讯模块,可在手机端进行日期.时间的校准 ...

  2. 单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》... 1

    引言 本设计以AT89S52单片机为控制核心,时钟芯片DS1302提供时钟源,配合LCD1602液晶显示模块,组成基本硬件系统,同时利用HC-05嵌入式蓝牙串口通讯模块,可在手机端进行日期.时间的校准 ...

  3. 第三篇,芯片启动和时钟系统

    芯片启动和时钟系统 1.芯片启动 首先stm32会根据启动方式(参考手册2.4节)从启动位置加载启动代码到内存中,之后开始执行启动代码,一般启动代码使用官方提供的即可 ---------- xxx.s ...

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

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

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

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

  6. 51单片机使用DS1302时钟芯片实现可调时钟

    文章目录 1.实现方法 2.所需函数模块 3.时钟写入(读取)函数(`DS1302.c`) 4.定时器初始化函数(`Timer0Init.c`) 5.按键扫描函数(`Key.c`) 6.时钟调整函数( ...

  7. 【C51单片机学习笔记--DS1302时钟芯片蜂鸣器I2C总线AT24C02存储器】

    C51单片机学习笔记–DS1302时钟芯片&&蜂鸣器&&I2C总线&&AT24C02存储器 文章目录 一.DS1302时钟芯片介绍 二.DS1302时钟 ...

  8. RK3568开发笔记-iSL1208 RTC时钟芯片调试记录

    文章目录 目录 文章目录 前言 一.RTC部分原理图 二.设备树配置 三.内核配置 四.设备信息查看 五.RTC时间读写设置 总结 前言 实时时钟的缩写是RTC(Real_Time Clock).RT ...

  9. 【51单片机快速入门指南】5.1:SPI与DS1302时钟芯片

    目录 硬知识 DS1302 简介 DS1302 使用 控制寄存器 日历/时钟寄存器 DS1302 的读写时序 电路设计 示例程序 DS1302.c DS1302.h 测试程序 main.c 实验现象 ...

最新文章

  1. Atitit.java jna  调用c  c++ dll的原理与实践  总结  v2  q27
  2. Java开发中模拟接口工具moco的使用
  3. android glide加载不出图片_Glide实现共享元素无缝转场效果,只需四步!
  4. redis 的线程模型
  5. 15个免费好用的抓包工具
  6. 第十七周助教工作总结——NWNU李泓毅
  7. 概率栅格地图中Uint8_t向int8_t转换
  8. 手机访问WEB项目图片404
  9. 金仓数据库KingbaseES数据库参考手册(服务器配置参数14. 版本和平台兼容性)
  10. STM32使用库函数点灯实验
  11. Mybatis的collection和association
  12. HashMap线程安全问题详细解析
  13. win7各种插件的下载与使用
  14. Mathon广告过滤规则发现
  15. SUP桨板电动气泵方案——鼎盛合方案
  16. java二进制视频_Java二进制概念(含视频)
  17. linux 编译gdal库下载,各个版本VS编译好的GDAL库下载
  18. Nginx的搭建和优化
  19. 红旗linux桌面版反应慢,亲自感受红旗Linux系统优化大全
  20. 2015年电视游戏大厅将逐一死掉?

热门文章

  1. QProcess文档
  2. 发软文外链技巧(你还在做无用功的软文外链吗)
  3. 百度移动强引蜘蛛软件3.0
  4. 用JAVA做一个物理动画_运用Java3D实现三维实时物理模拟动画
  5. UE4中Actor、Pawn、Character等各种类的详细了解。
  6. Python廖雪峰--面相对象高级编程学习
  7. Says Of Heart!
  8. Python快速实现网页工具的利器
  9. 联合办公空间是什么,跟传统办公室有什么区别
  10. Faster-RCNN PRN网络解析