小白跟做江科大51单片机之DS1302可调时钟

原理部分

1.DS1302可调时钟介绍

单片机定时器主要占用CPU时间,掉电不能继续运行

图1

2.原理

图2

内部有寄存器,寄存的时候以时分秒寄存,以通信协议实现数据交互,就可以实现对数据进行访问和读写

3.主要寄存器定义

CE芯片使能,IO数据输入输出,相当于时序电路中的SER,SCLK:串行时钟

图3

第6位为0表示到CK——时钟,第0位为0表示WR——写

CE写入给1,写完给0

4.时序图

图4

5.BCD码

图5


代码部分

1.新建项目引入LCD1602

2.编写DS1302_con.c和DS1302_con.h文件

①DS1302_con.h

#ifndef __DS1302_CON_H__
#define __DS1302_CON_H__

void DS1302_Init();
void DS1302_Write(unsigned char command,Data);
unsigned char DS1302_Read(unsigned char command);
 
#endif

②DS1302_con.c

#include <REGX52.H>
sbit DS1302_SCLK=P3^6;
sbit DS1302_CE=P3^5;
sbit DS1302_IO=P3^4;

//刚开始单片机上电,所有端口默认为1,所以需要调0
void DS1302_Init()
{
    DS1302_SCLK=0;
    DS1302_CE=0;
}

void DS1302_Write(unsigned char command,Data)
{
    unsigned char i;
    DS1302_CE=1;
    for(i=0;i<8;i++)
    {
        //IO从最低位开始读
        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;
}

unsigned char DS1302_Read(unsigned char command)
{
    unsigned char i,Data=0x00;
    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);   //这里第一次运行就相当于Data已经拿到了第0位数据,只是在存入Data
        }
    }
    DS1302_CE=0;
    DS1302_IO=0;       //这里要把IO口置位0,清空IO缓存,否则输出数字会闪烁不定
    return Data;
}

3.main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302_con.h"
#include "Delay.h"

void main()
{
    unsigned char sec;
    LCD_Init();
    DS1302_Init();
    LCD_ShowString(1,1,"RTC");
    DS1302_Write(0x8e,0x00);              //关闭写保护,没有这一行则可能显示数字大于59且不动
    DS1302_Write(0x80,0x03);         //写入秒时0x80,可看图3
    while(1)
    {

      sec=DS1302_Read(0x81);    //读取秒时0x81,可看图3

      LCD_ShowNum(2,1,sec/16*10+sec%16,3);    //这里有一个BCD转10进制的计算,可看图5
    }
}

到这一步可验证结果是否秒钟的递增数字是否显示正常

4.显示时分秒以及年月日

①DS1302_con.h

#ifndef __DS1302_CON_H__
#define __DS1302_CON_H__

void DS1302_Init();
void DS1302_Write(unsigned char command,Data);
unsigned char DS1302_Read(unsigned char command);
extern unsigned char DS1302_Time[];
 
#endif

②DS1302_con.c

#include <REGX52.H>

//寄存器写入地址/指令定义
#define DS1302_SECOND        0x80
#define DS1302_MINUTE        0x82
#define DS1302_HOUR            0x84
#define DS1302_DATE            0x86
#define DS1302_MONTH        0x88
#define DS1302_YEAR            0x8C
#define DS1302_WP              0x8E

sbit DS1302_SCLK=P3^6;
sbit DS1302_CE=P3^5;
sbit DS1302_IO=P3^4;

//年、月、日、时、分、秒
unsigned char DS1302_Time[] = {24,2,29,11,11,26};


//刚开始单片机上电,所有端口默认为1,所以需要调0
void DS1302_Init()
{
    DS1302_SCLK=0;
    DS1302_CE=0;
}

void DS1302_Write(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;
}

unsigned char DS1302_Read(unsigned char command)
{
    unsigned char i,Data=0x00;
    //更改命令的最后一位,减少代码
    command|=1;
    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);   //这里第一次运行就相当于Data已经拿到了第0位数据,只是在存入Data
        }
    }
    DS1302_CE=0;
    DS1302_IO=0;
    return Data;
}

//时间的写入
void DS1302_SetTime()   
{
    DS1302_Write(DS1302_WP,0x00);//取消写保护
    DS1302_Write(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);//十进制转BCD码后写入
    DS1302_Write(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
    DS1302_Write(DS1302_DATE,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
    DS1302_Write(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
    DS1302_Write(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
    DS1302_Write(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
    DS1302_Write(DS1302_WP,0x00);//打开写保护
}

void DS1302_showTime() 
{
    unsigned char temp;
    temp=DS1302_Read(DS1302_YEAR);
    DS1302_Time[0]=temp/16*10+temp%16;

    temp=DS1302_Read(DS1302_MONTH);
    DS1302_Time[1]=temp/16*10+temp%16;
    
    temp=DS1302_Read(DS1302_DATE);
    DS1302_Time[2]=temp/16*10+temp%16;
    
    temp=DS1302_Read(DS1302_HOUR);
    DS1302_Time[3]=temp/16*10+temp%16;
    
    temp=DS1302_Read(DS1302_MINUTE);
    DS1302_Time[4]=temp/16*10+temp%16;
    
    temp=DS1302_Read(DS1302_SECOND);
    DS1302_Time[5]=temp/16*10+temp%16;
    
}
③main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302_con.h"
#include "Delay.h"

void main()
{
    LCD_Init();
    DS1302_Init();
    LCD_ShowString(1,1,"  -  -  ");
    LCD_ShowString(2,1,"  :  :  ");
    DS1302_SetTime();      //这句循环写入多个命令,相当于之前的 DS1302_Write(0x80,0x03); 
    
    while(1)
    {
        DS1302_showTime();   //这句相当于多个之前的sec=DS1302_Read(0x81);
        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);
        
    }
}

即可实现以下效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/732366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js对象 静态方法和实例方法

求下面代码的输出结果&#xff1a; 首先先分析一下上面各函数&#xff1a; Person.say function(){console.log("a")} 第一个say()方法是定义在Person函数身上的&#xff0c;我们如果想使用这个方法&#xff0c;可以通过Person().say()来调用 this.say function()…

【Docker7】Docker安全及https安全认证

Docker安全及https安全认证一、Docker 容器与虚拟机的区别1、隔离与共享2、性能与损耗3、不同点 二、Docker 存在的安全问题1、Docker 自身漏洞2、Docker 源码问题 三、Docker 架构缺陷与安全机制1、容器之间的局域网攻击2、DDoS 攻击耗尽资源2.1 什么叫CC攻击&#xff1f;什么…

Python实现汉诺塔演示程序

Python实现汉诺塔演示程序 汉诺塔问题 一个板子上有三根柱子以及一些大小各不相同的圆盘。我们分别把这三根柱子叫做起始柱A、辅助柱B及目标柱C&#xff0c;汉诺塔移动圆盘的规则如下&#xff1a; 把起始柱A上所有的圆盘都移动到C柱&#xff0c;且在移动过程中始终保持圆盘从…

先进电机技术 —— 伺服驱动器与变频器

一、变频器与伺服驱动器发展趋势 在近年来的技术发展中&#xff0c;变频器和伺服驱动器均呈现出显著的先进性提升和技术融合趋势&#xff0c;以下是一些主要的发展方向&#xff1a; ### 变频器的发展趋势&#xff1a; 1. **智能化与网络化**&#xff1a; - 高级变频器集成…

【知识分享】自动化测试首选接口自动化?

在分层测试的“金字塔”模型中&#xff0c;接口测试属于第二层服务集成测试范畴。 相比UI自动化测试而言&#xff0c;接口自动化测试收益更大&#xff0c;且容易实现&#xff0c;维护成本低&#xff0c;有着更高的投入产出比。因此&#xff0c;项目开展自动化测试的首选一般为接…

计算机网络(基础篇)复习笔记——体系结构/协议基础(持续更新中......)

目录 1 计算机网络基础相关技术Rip 路由更新操作 2 体系结构(OSI 7层, TCP/IP4层)应用层运输层网络层IPv4无分类域间路由选择 CIDRIPV6 数据链路层循环冗余校验CRC协议设备 物理层传输媒体信道复用技术宽带接入技术数据通信 3 网络局域网(以太网Ethernet) 4 通信过程编码:信道极…

vue router 解决路由带参数跳转时出现404问题

我的页面是从一个vue页面router跳转到另一个vue页面&#xff0c;并且利用windows.open() 浏览器重新创建一个页签。但是不知道为什么有时候可以有时候又不行&#xff0c;经过反复测试与分析&#xff0c;最终发现是因为有一个参数的值里包含了小数点., 小数点是浏览器合法字符&a…

Pytest测试中的临时目录与文件管理!

在Pytest测试框架中&#xff0c;使用临时目录与文件是一种有效的测试管理方式&#xff0c;它能够确保测试的独立性和可重复性。在本文中&#xff0c;我们将深入探讨如何在Pytest中利用临时目录与文件进行测试&#xff0c;并通过案例演示实际应用。 为什么需要临时目录与文件&a…

#KEIL使用

关于在调试时&#xff0c;有些局部变量值无法在窗口中查看报错“not in scope"&#xff0c;是被优化掉了&#xff0c;降低优化等级即可。 参考博客&#xff1a; KeilMDK 开发过程中遇到一些奇怪问题记录_keil遇到了不正当的冲突-CSDN博客

全国保护性耕作/常规耕作农田分类数据集

基于Sentinel-2遥感产品&#xff0c;使用来自文献调研和目视解译产生的保护性/常规耕作样本点&#xff0c;通过交叉验证方法训练随机森林分类器&#xff0c;生成了2016-2020年全国保护性耕作/常规耕作农田分类数据集。分类代码&#xff1a;0值代表非农田&#xff0c;1值表示第一…

“轻松入门Electron:一步步构建梦想中的桌面软件

在数字化的浪潮中&#xff0c;桌面应用依旧占据着其独特而重要的位置&#xff0c;不论是在企业解决方案、专业工具软件还是个性化应用领域中都是如此。随着技术的演进&#xff0c;创建这些应用的过程已经变得更为简单和可行&#xff0c;尤其是随着Electron等框架的出现。Electr…

【异常处理】sbt构建Chisel库时出现extracting structure failed:build status:error的解决办法

文章目录 报错背景&#xff1a;解决思路&#xff1a;①IDEA中配置本地的SBT进行下载②更改下载源为华为的镜像站1. 修改sbtconfig.txt2. 增加repositories文件 ③查看报错信息 总结整理的Scala-Chisel-Chiseltest版本信息对应表 报错背景&#xff1a; 最近在写Chisel时&#x…

K8s-MySQL主从集群

K8s-MySQL主从集群 引言 该案例代码均可从https://github.com/WeiXiao-Hyy/k8s_example 获取&#xff0c;欢迎Star&#xff01; 需求 一个“主从复制”的MySQL集群有一个主节点Master有多个从节点Slave从节点需要能水平扩展所以写操作只能在主节点上执行读操作可以在所有节点…

Navicat Premium:掌控数据库的强大工具

在当今数字化的时代&#xff0c;数据管理变得越来越重要。无论您是数据库管理员、开发人员还是普通用户&#xff0c;找到一个高效、易用的数据库管理工具是至关重要的。Navicat Premium for Mac/Win 就是这样一款强大的多协议数据库管理工具&#xff0c;它将为您的数据库管理体…

HPE ProLiant MicroServer Gen8 RAID 1 扩容、故障恢复探索

声明&#xff1a;本探索只针对HP Microserver Gen8 Smart Array B120i板载阵列卡组建RAID 1&#xff08;不是RAID 10&#xff09;&#xff0c;不同阵列卡结果可能会不同&#xff0c;请谨慎操作&#xff0c;本人不对你操作后导致的任何数据丢失或者损失承担任何责任&#xff0c;…

Java SE入门及基础(29)

第三节 访问修饰符 1. 概念 访问修饰符就是控制访问权限的修饰符号 2. 类的访问修饰符 类的访问修饰符只有两种&#xff1a;public 修饰符和默认修饰符&#xff08;不写修饰符就是默认&#xff09; public 修饰符修饰类表示类可以公开访问。默认修饰符修饰类表示该类只能…

融资项目——网关微服务

1. 网关的路由转发功能 在前后端分离的项目中&#xff0c;网关服务可以将前端的相关请求转发到相应的后端微服务中。 2. 网关微服务的配置 首先需要创建一个网关微服务&#xff0c;并添加依赖。 <!-- 网关 --><dependency><groupId>org.springframework.cl…

FreeRTOS学习笔记-基于stm32(3)中断管理

一、什么是中断 通俗点讲就是让CPU停止当前在做的事&#xff0c;转而去做更紧急的事。 二、中断优先级分组 这个紧急的事也有一个等级之分&#xff0c;优先级越高越先执行。stm32使用中断优先配置寄存器的高4位&#xff0c;共16级的中断优先等级。 stm32的中断优先等级可以分为…

让开源浏览器Chromium正常显示中文

什么是 Chromium &#xff1f; Chromium 是一个开源浏览器项目&#xff0c;旨在为所有用户构建一种更安全、更快、更稳定的网络体验方式。 和老苏之前介绍的 Firefox 的作用是一样的 文章传送门&#xff1a;给群晖安装firefox浏览器 因为是基于 vnc 的应用&#xff0c;感觉资源…

Elasticsearch 通过索引阻塞实现数据保护深入解析

Elasticsearch 是一种强大的搜索和分析引擎&#xff0c;被广泛用于各种应用中&#xff0c;以其强大的全文搜索能力而著称。 不过&#xff0c;在日常管理 Elasticsearch 时&#xff0c;我们经常需要对索引进行保护&#xff0c;以防止数据被意外修改或删除&#xff0c;特别是在进…