STM32驱动DS1302

本文围绕STM32与DS1302展开,介绍了DS1302的读写时序、寄存器表等知识,给出了BCD码转十进制计算方法和完整程序。同时分享了开发中遇到的问题,如秒寄存器读操作右移次数不对、时间进位异常等,并阐述了解决办法和反思。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DS1302 概述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

时序图分析

在这里插入图片描述
理解说明:
      先说单字节写时序,首先,字节序开始。SCLK = 低电平,RST = 0,接着RST = 1,这里要注意datasheet中的时间,不过对于72Mhz MCU,IO翻转速度也能够满足。开始后,IO就要准备发送的命令寄存器了,先发送低位再发送高位可以看出,IO总是先准备好数据,接着SCLK上升沿,送入数据。 每次都是先发送命令寄存器,再去发送8bits数据。写入完毕后,SCLK = 0,RST = 0,表示字节序结束。
读时序:
      首先,字节序开始。SCLK = 0,RST = 0,RST = 1。在SCLK的时钟信号下,IO发送给DS1302的字节序,低位先发送,高位最后,这里和写字节序同理,IO先准备好数据,然后在SCLK的上升沿时候送入数据。==Warning:==读字节序,是下降沿读取,而且在写字节序的最后一个时钟脉冲的下降沿,已经是读取第一位了,可以看出总共有15个时钟脉冲,这与写时序16个脉冲还有点区别。最后在下降沿下,依次读取8bits数据。
      如果有不足之处,请欢迎改正。

读写时序

      可以看出,向控制寄存器0x8E地址写入0x00(取消写保护),然后再从0x8E地址读取出来为0x00,表示取消了写保护,此时我们可以向DS1302的可写寄存器进行写入值了。以下是逻辑分析仪抓取的波形。注意:发送、接收数据都是低位先发送,低位先接收。
写保护寄存器读写操作:
在这里插入图片描述

读取星期寄存器:0x8B
在这里插入图片描述

读取小时寄存(0x85)器数据在这里插入图片描述

寄存器表

在这里插入图片描述

重点寄存器描述

时钟暂停

在这里插入图片描述

AM-PM/12-24方式

在这里插入图片描述

写保护寄存器

在这里插入图片描述
比如,想要自己设置时间的时候或者朝RAM中写入东西前,bit7必须为0

慢速充电(Trickle charge)寄存器

这部分建议看手册,这部分可以通过设置寄存器来达到给备用电池充电的目的,电池可以是超级电容,也可以是微型锂电池。

其它部分

晶振和电源

在这里插入图片描述

BCD码转十进制计算

8421 BCD码是最基本和最常用的BCD码,它和四位自然二进制码相似,各位的权值为8、4、2、1,故称为有权BCD码。和四位自然二进制码不同的是,它只选用了四位二进制码中前10组代码,即用0000~1001分别代表它所对应的十进制数,余下的六组代码不用。
DS1302使用的是8421 BCD码,十进制范围是0~9。
在这里插入图片描述

举例:秒寄存器转为10进制值
第一种方法:

dstime.get_time.second = second/16*10+second%16;

第二种方法:

 dstime.get_time.second = ((second & 0x70)>>4)*10 + (second & 0x0F);

简单点说就是,取出一个字节的高4位作为十进制的十位,取出字节中的低4位作为十进制的个位,然后相加组合成秒,同样,其它的日期也是同理。

完整的程序

平台和配置:

芯片:STM32F103C8T6
IDE:STM32Cubemx,CLion
下载:ST-Link V2
逻辑分析仪:某宝30块8通道,软件:Logic2.4.7
注意事项:CLion中printf重定向和Keil中不一样问题!

main.c

#include "ds1302.h"
int main(void)
{
   
	ds1302_init();
	while(1)
	{
   
		print_times();
		HAL_Delay(500);
	}

}

ds1302.h

//
// Created by lxp on 2024/3/29.
//

#ifndef CLOCK_DS1302_H
#define CLOCK_DS1302_H
#include "stm32f1xx.h"

#define DS1302_GPIO  GPIOB
#define DS1302_DATA  GPIO_PIN_12
#define DS1302_CLK   GPIO_PIN_13
#define DS1302_RST   GPIO_PIN_14

#define DS1302_DATA_IN      {
      GPIOB->CRH &= 0xfff0ffff; GPIOB->CRH |= (uint32_t)(8<<16); }
#define DS1302_DATA_OUT     {
      GPIOB->CRH &= 0xfff0ffff; GPIOB->CRH |= (uint32_t)(3<<16); }

#define DS1302_DATA_LOW     HAL_GPIO_WritePin(DS1302_GPIO,DS1302_DATA,GPIO_PIN_RESET)
#define DS1302_DATA_HIGH    HAL_GPIO_WritePin(DS1302_GPIO,DS1302_DATA,GPIO_PIN_SET)

#define DS1302_CLK_LOW      HAL_GPIO_WritePin(DS1302_GPIO,DS1302_CLK,GPIO_PIN_RESET)
#define DS1302_CLK_HIGH     HAL_GPIO_WritePin(DS1302_GPIO,DS1302_CLK,GPIO_PIN_SET)

#define DS1302_RST_LOW      HAL_GPIO_WritePin(DS1302_GPIO,DS1302_RST,GPIO_PIN_RESET)
#define DS1302_RST_HIGH     HAL_GPIO_WritePin(DS1302_GPIO,DS1302_RST,GPIO_PIN_SET)
typedef struct _time{
   
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t week;
    uint8_t hours;
    uint8_t minute;
    uint8_t second;
}_Time;

typedef struct _time_user{
   
    _Time set_time;
    _Time get_time;
}Time;

extern Time dstime;

//register addr
//写保护寄存器
#define WRITE_PROTECT  0x8e
#define WRITE_PROTECT_CLOSE     0x00
#define WRITE_PROTECT_OPEN      0x80

#define SECONDE_ADDR   0x80
#define MINUTE_ADDR    0x82
#define HOURS_ADDR     0x84
#define DAY_ADDR       0x86
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值