基于STM32的DS1302实时时钟模块应用

DS1302是一款低功耗的实时时钟芯片,被广泛应用于各种电子产品中。它具有准确计时、多种时间格式表示、定时报警等功能,适用于记录时间、日期和闹钟。在本文中,我们将介绍如何在基于STM32的开发环境中使用DS1302实时时钟模块,并给出一个完整的示例代码。

硬件连接:
首先,我们需要准备以下硬件:
- STM32单片机开发板
- DS1302实时时钟模块

连接方法如下:
- 将DS1302的SCK引脚连接到STM32的SCK引脚
- 将DS1302的SDA引脚连接到STM32的SDA引脚
- 将DS1302的RST引脚连接到STM32的RST引脚
- 将DS1302的VCC引脚连接到STM32的VCC引脚(一般为3.3V)
- 将DS1302的GND引脚连接到STM32的GND引脚

软件实现:
以下是一个基于STM32的DS1302实时时钟模块应用的示例代码:

```c
#include "stm32f10x.h"
#include "ds1302.h"

int main(void)
{
    // 初始化DS1302模块
    DS1302_Init();

    while (1)
    {
        // 读取实时时钟的时间
        uint8_t hour, minute, second;
        DS1302_GetTime(&hour, &minute, &second);

        // 读取实时时钟的日期
        uint8_t year, month, day;
        DS1302_GetDate(&year, &month, &day);

        // 在串口输出时间和日期
        printf("Current time: %02d:%02d:%02d\r\n", hour, minute, second);
        printf("Current date: %02d-%02d-%02d\r\n", year, month, day);

        // 延时一段时间
        delay_ms(1000);
    }
}
```

以上是一个简单的应用示例,该示例通过DS1302模块获取当前的时间和日期,并通过串口输出。在实际应用中,可以根据需要添加其他功能,如定时报警、时间设置等。

需要注意的是,在使用该示例代码之前,你需要提前编写一个适配器库`ds1302.h`和`ds1302.c`,用于实现DS1302模块的初始化、读写时间和日期等操作。你可以根据DS1302的数据手册编写适配器库,或者找到第三方提供的库。

接下来,我们将详细介绍如何编写`ds1302.h`和`ds1302.c`,以及其中的各个函数的实现。在这份代码中,我们假设使用的是STM32的标准外设库进行开发。

ds1302.h:

```c
#ifndef DS1302_H
#define DS1302_H

#include <stdint.h>

void DS1302_Init(void);
void DS1302_GetTime(uint8_t *hour, uint8_t *minute, uint8_t *second);
void DS1302_GetDate(uint8_t *year, uint8_t *month, uint8_t *day);
void DS1302_SetTime(uint8_t hour, uint8_t minute, uint8_t second);
void DS1302_SetDate(uint8_t year, uint8_t month, uint8_t day);

#endif
```

ds1302.c:

```c
#include "ds1302.h"
#include "stm32f10x.h"

// DS1302模块引脚定义
#define DS1302_RST_PIN GPIO_Pin_0
#define DS1302_SCK_PIN GPIO_Pin_1
#define DS1302_IO_PIN GPIO_Pin_2
#define DS1302_PORT GPIOB

// DS1302模块相关函数
void DS1302_WriteByte(uint8_t dat)
{
    uint8_t i;
    for (i = 0; i < 8; i++)
    {
        GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
        if (dat & 0x01)
            GPIO_SetBits(DS1302_PORT, DS1302_IO_PIN);
        else
            GPIO_ResetBits(DS1302_PORT, DS1302_IO_PIN);
        GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
        dat >>= 1;
    }
}

uint8_t DS1302_ReadByte(void)
{
    uint8_t i, dat = 0;
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(DS1302_PORT, &GPIO_InitStructure);

    for (i = 0; i < 8; i++)
    {
        dat >>= 1;
        GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
        if (GPIO_ReadInputDataBit(DS1302_PORT, DS1302_IO_PIN))
            dat |= 0x80;
        GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
    }

    return dat;
}

void DS1302_Write(uint8_t reg, uint8_t dat)
{
    GPIO_ResetBits(DS1302_PORT, DS1302_RST_PIN);
    DS1302_WriteByte(reg);
    DS1302_WriteByte(dat);
    GPIO_SetBits(DS1302_PORT, DS1302_RST_PIN);
}

uint8_t DS1302_Read(uint8_t reg)
{
    uint8_t dat;
    GPIO_ResetBits(DS1302_PORT, DS1302_RST_PIN);
    DS1302_WriteByte(reg | 0x81);
    dat = DS1302_ReadByte();
    GPIO_SetBits(DS1302_PORT, DS1302_RST_PIN);

    return dat;
}

void DS1302_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DS1302_RST_PIN | DS1302_SCK_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(DS1302_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_Init(DS1302_PORT, &GPIO_InitStructure);

    DS1302_Write(0x8e, 0x00);  // 写入禁止写保护命令
}

void DS1302_GetTime(uint8_t *hour, uint8_t *minute, uint8_t *second)
{
    uint8_t data[3];
    for (int i = 0; i < 3; i++)
    {
        data[i] = DS1302_Read(0x81 + i * 2);  // 从RAM中读取时间数据
        if (i == 0)
            *second = ((data[0] & 0x0F) + (data[0] >> 4) * 10);
        else if (i == 1)
            *minute = ((data[1] & 0x0F) + (data[1] >> 4) * 10);
        else
            *hour = ((data[2] & 0x0F) + (data[2] >> 4) * 10);
    }
}

void DS1302_GetDate(uint8_t *year, uint8_t *month, uint8_t *day)
{
    uint8_t data[3];
    for (int i = 0; i < 3; i++)
    {
        data[i] = DS1302_Read(0x81 + i * 2 + 6);  // 从RAM中读取日期数据
        if (i == 0)
            *day = ((data[0] & 0x0F) + (data[0] >> 4) * 10);
        else if (i == 1)
            *month = ((data[1] & 0x0F) + (data[1] >> 4) * 10);
        else
            *year = ((data[2] & 0x0F) + (data[2] >> 4) * 10);
    }
}

void DS1302_SetTime(uint8_t hour, uint8_t minute, uint8_t second)
{
    // 禁止写保护
    DS1302_Write(0x8e, 0x00);
    
    // 写入时间数据到RAM
    DS1302_Write(0x80, (second / 10) << 4 | (second % 10));
    DS1302_Write(0x82, (minute / 10) << 4 | (minute % 10));
    DS1302_Write(0x84, (hour / 10) << 4 | (hour % 10));

    // 打开写保护
    DS1302_Write(0x8e, 0x80);
}

void DS1302_SetDate(uint8_t year, uint8_t month, uint8_t day)
{
    // 禁止写保护
    DS1302_Write(0x8e, 0x00);

    // 写入日期数据到RAM
    DS1302_Write(0x86, (day / 10) << 4 | (day % 10));
    DS1302_Write(0x88, (month / 10) << 4 | (month % 10));
    DS1302_Write(0x8c, (year / 10) << 4 | (year % 10));

    // 打开写保护
    DS1302_Write(0x8e, 0x80);
}
```

以上是一个基于STM32的DS1302实时时钟模块的完整示例代码。在这个示例中,我们实现了DS1302模块的初始化,读取时间和日期,设置时间和日期等操作,并给出了相应的函数实现。需要注意的是,具体的引脚定义、外设时钟使能等操作可能会根据你的实际硬件环境而有所不同,你需要根据自己的实际情况进行相应的调整。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

代码获取、问题探讨及文章转载可私信。

 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

傻瓜式教学Docker 使用docker compose部署 php nginx mysql

首先你可以准备这个三个服务,也可以在docker compose 文件中 直接拉去指定镜像,这里演示的是镜像服务已经在本地安装好了,提供如下: PHP # 设置基础镜像 FROM php:8.2-fpm# install dependencies RUN apt-get update && apt-get install -y \vim \libzip-dev \libpng…

基于稀疏表示的小波变换多光谱图像融合算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 小波变换融合 PCA融合 基于稀疏表示的小波变换多光谱图像融合算法 性能指标对比 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...........…

java八股 spring + mybatis

Spring常用注解&#xff08;绝对经典&#xff09;_spring注解-CSDN博客 框架篇-02-Spring-单例bean是线程安全的吗_哔哩哔哩_bilibili 1.spring.bean 单例 线程不安全 2.AOP 项目里可以说记录用户登录日志&#xff0c;利用request去获取姓名、ip、、请求方式、url&#xff0…

ros2中gazebo安装的注意事项

Install From source&#xff08;推荐安装Fortress版本&#xff0c;好像很方便&#xff09; ROS Be sure youve installed ROS Humble (at least ROS-Base). More ROS dependencies will be installed below. Gazebo Install either Edifice, Fortress, or Garden.(没有har…

MFC 运行时类信息机制

目录 运行时类信息机制概述 测试 宏代换分析 结构体 CRuntimeclass 函数 GetRuntimeClass() 总结 执行过程分析 运行时类信息机制概述 在程序运行过程中可以获知对象的类的相关信息&#xff08;例如∶对象是否属于某个类) 如何使用&#xff1f; 类必须派生自CObject类…

MFC 动态创建机制

目录 动态创建机制概述 代码测试分析 执行过程 总结 动态创建机制概述 MFC 动态创建机制是 MFC 中的一项重要功能&#xff0c;它允许开发者在运行时动态创建和管理窗口控件。通过动态创建机制&#xff0c;开发者可以根据需要在程序运行过程中创建、显示和销毁窗口&#xf…

【K8S in Action】服务:让客户端发现pod 并与之通信(2)

一 通过Ingress暴露服务 Ingress (名词&#xff09; 一一进入或进入的行为&#xff1b;进入的权利&#xff1b;进入的手段或地点&#xff1b;入口。一个重要的原因是每个 LoadBalancer 服务都需要自己的负载均衡器&#xff0c; 以及 独有的公有 IP 地址&#xff0c; 而 Ingres…

基于STM32的DS1302实时时钟模块应用及原理介绍

在嵌入式系统中&#xff0c;实时时钟模块是一个常见的功能模块&#xff0c;用于记录和管理系统的时间信息。DS1302是一款低功耗、具有多种功能的实时时钟芯片&#xff0c;被广泛应用于各种电子产品中。本文将介绍基于STM32微控制器的DS1302实时时钟模块的应用及原理&#xff0c…

案例163:基于微信小程序的校园二手交易平台系统设计与开发

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

快速入门学习定时任务框架-xxljob

定时任务框架-xxljob 简介 主要用于分布式任务调度&#xff0c;可以将任务调度和执行分布在多个节点上。它提供了一个集中式的管理平台&#xff0c;支持动态添加、修改、删除任务&#xff0c;以及任务的分片执行&#xff0c;确保任务在分布式环境中的高可用性的一个框架 spr…

OSI 七层参考模型及TCP/IP 四层模型

OSI 七层参考模型 七层模型&#xff0c;亦称 OSI &#xff08; Open System Interconnection &#xff09;参考模型&#xff0c;即开放式系统互联。参考模型是国际标准化组织&#xff08;ISO &#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为…

在使用 npm install的时候提示node-sass command faile 解决方案

在使用npm install的时候错误提示node-sass 相关的。错误信息如下图&#xff1a; 解决方法&#xff08;PS&#xff1a;凯哥的不适用&#xff09; 出现这种问题基本是由于node版本与sass版本不匹配导致的 方案1&#xff1a;卸载node&#xff0c;安装对应版本 方案2&#xff1…

基于Arduino和HC-SR04的超声波测距系统设计

本文介绍了如何使用Arduino和HC-SR04超声波传感器设计并构建一个简单的超声波测距系统。我们将详细讨论硬件连线和编程步骤&#xff0c;并提供完整的Arduino代码。此系统可以应用于各种需要测量距离的项目&#xff0c;例如智能车辆、机器人和安防系统。 引言&#xff1a; 超声…

工具系列:PyCaret介绍_编写和训练自定义机器学习模型

文章目录 PyCaret安装PyCaret&#x1f449; 让我们开始吧&#x1f449; 数据集&#x1f449; 数据准备PyCaret中的设置函数&#x1f449; 可用模型&#x1f449; 模型训练与选择&#x1f449; 编写和训练自定义模型&#x1f449; GPLearn模型&#x1f449; NGBoost 模型&#x…

解决log4j多个日志都写到一个文件

之前客户端程序由于Websockt包依赖的log4j&#xff0c;就用log4j写日志了&#xff0c;Web用的log4j2没毛病。用log4j的多个logger的日志都写到一个文件里了&#xff0c;查了很多资料都没解决。今天闲了解决一下。 最后好使的配置 # 设置日志根 log4j.rootLogger INFO,Except…

嵌入式开发中利用strstr()对部分模块回传数据进行解析的问题(坑)

受到以下博文的启发&#xff1a; https://www.cnblogs.com/yup1983/p/11337837.html 验证&#xff1a; 最近通过ESP8266远程控制小车&#xff0c;在wifi回传的数据解析过程中遇到标题所述的烦恼 如上截图所示&#xff0c;数据回传过程中会接受到‘\0’字节对应的ASCII码为0x0…

基于IPP-FFT的线性调频Z(Chirp-Z,CZT)的C++类库封装并导出为dll(固定接口支持更新)

上一篇分析了三种不同导出C++类方法的优缺点,同时也讲了如何基于IPP库将FFT函数封装为C++类库,并导出为支持更新的dll库供他人调用。 在此基础上,结合前面的CZT的原理及代码实现,可以很容易将CZT变换也封装为C++类库并导出为dll,关于CZT的原理和实现,如有问题请参考: …

大数据应用开发1——配置基础环境

一、基础环境配置 1.配置虚拟网络 1.1、点击1、编辑2和3&#xff0c; 1.2、点开4&#xff0c;编辑网关 2、配置虚拟机环境 1.1、安装一台虚拟机&#xff0c;使用root用户登录&#xff0c;打开终端 1.2修改主机名 终端输入&#xff1a; vim /etc/hostname使用vim编辑/etc/ho…

MQ(消息队列)相关知识

1. 什么是mq 消息队列是一种“先进先出”的数据结构 2. 应用场景 其应用场景主要包含以下3个方面 应用解耦 系统的耦合性越高&#xff0c;容错性就越低。以电商应用为例&#xff0c;用户创建订单后&#xff0c;如果耦合调用库存系统、物流系统、支付系统&#xff0c;任何…

SpringMVC核心处理流程梳理

1、处理流程图展示 当我拿出这张图&#xff0c;阁下又该如何应对呢&#xff1f;执行流程是不是一目了然了。 2、DispatcherServlet&#xff1a;中央处理器或者中央调度器 下图官方的解释应该最完善了。 3、SpringMVC三大核心组件 HandlerMapping 处理器映射器&#xff0c;…