最近更新于 2024-05-05 12:32
前言
这个模块通过 DS1302 芯片进行计时,支持年、月、日、周、时、分、秒,对于闰年以及不同月份不同天数可以自动调整,可以按 12 小时制或 24 小时制工作。芯片中有 31 Byte 的 SRAM,当前时钟就存储在里面。可以通过串行接口和单片机通信,模块上的电池可以保证在断开 VCC 引脚连接后依然正常工作,不依赖引脚供电。
测试环境
Arduino UNO
Arduino IDE 2.1.1(
Ds1302 1.0.4:https://github.com/Treboada/Ds1302
)
接线
\begin{array}{|c|c|}
\hline
DS1302 模块 & Arduino \\
\hline
VCC & 5V \\
\hline
GND & GND \\
\hline
CLK & 2 \\
\hline
DAT & 3 \\
\hline
RST & 4 \\
\hline
\end{array}
进行串行通信的接口连接的 3 个引脚可以自定,只是要和代码匹配
代码示例
设置时间
#include <Ds1302.h>
#define CLK 2
#define DAT 3
#define RST 4
Ds1302 rtc(RST, CLK, DAT);
uint8_t parseDigits(char* str, uint8_t count)
{
uint8_t val = 0;
while (count-- > 0) {
val = (val * 10) + (*str++ - '0');
}
return val;
}
void setup()
{
rtc.init();
Serial.begin(9600);
Serial.println("请输入日期和时间 (YYMMDDWhhmmss): ");
}
void loop()
{
static char buffer[13];
static uint8_t char_idx = 0;
if (char_idx == 13)
{
Ds1302::DateTime dt;
dt.year = parseDigits(buffer, 2);
dt.month = parseDigits(buffer + 2, 2);
dt.day = parseDigits(buffer + 4, 2);
dt.dow = parseDigits(buffer + 6, 1);
dt.hour = parseDigits(buffer + 7, 2);
dt.minute = parseDigits(buffer + 9, 2);
dt.second = parseDigits(buffer + 11, 2);
rtc.setDateTime(&dt);
char_idx = 0;
}
if (Serial.available())
{
buffer[char_idx++] = Serial.read();
}
}
比如要设置时间为 2023-8-20 星期日 19:00:00,则输入 2308207190000
读取时间
#include <Ds1302.h>
#define CLK 2
#define DAT 3
#define RST 4
Ds1302 rtc(RST, CLK, DAT);
const static char* WeekDays[] =
{
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
"星期日"
};
void setup()
{
Serial.begin(9600);
rtc.init(); // 初始化实时时钟模块
// 首次使用没有设置时间,需要先设置时间再启动
if (rtc.isHalted())
{
Serial.println("实时时钟模块已停止,正在设置时间......");
Ds1302::DateTime dt =
{
.year = 23,
.month = Ds1302::MONTH_AUG,
.day = 20,
.hour = 19,
.minute = 00,
.second = 00,
.dow = Ds1302::DOW_SUN
};
rtc.setDateTime(&dt);
}
}
void loop()
{
Ds1302::DateTime now;
rtc.getDateTime(&now); // 读取当前时间
static uint8_t last_second = 0;
if (last_second != now.second)
{
last_second = now.second;
Serial.print("20");
Serial.print(now.year);
Serial.print('-');
if (now.month < 10)
{
Serial.print('0');
}
Serial.print(now.month);
Serial.print('-');
if (now.day < 10)
{
Serial.print('0');
}
Serial.print(now.day);
Serial.print(' ');
Serial.print(WeekDays[now.dow - 1]);
Serial.print(' ');
if (now.hour < 10)
{
Serial.print('0');
}
Serial.print(now.hour);
Serial.print(':');
if (now.minute < 10)
{
Serial.print('0');
}
Serial.print(now.minute);
Serial.print(':');
if (now.second < 10)
{
Serial.print('0');
}
Serial.print(now.second);
Serial.println();
}
delay(200);
}
DS1302 实时时钟模块