【花雕学编程】Arduino动手做(245)---DS3231高精度时钟模块之通过 I2C 通信 接收用户输入的时间数据并更新时钟

在这里插入图片描述

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题,希望能够抛砖引玉。

** 【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百四十五:DS3231 高精度时钟模块 IIC/I2C接口 实时计时传感器**

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
实验模块接线示意图

在这里插入图片描述

【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百四十五:DS3231 高精度时钟模块 IIC/I2C接口 实时计时传感器
项目之八:通过 I2C 通信 接收用户输入的时间数据并更新时钟

实验开源代码

/*
  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之八:通过 I2C 通信 接收用户输入的时间数据并更新时钟
*/

#include <DS3231.h>  // 引入 DS3231 RTC 库
#include <Wire.h>    // 引入 I2C 通信库

// **创建 DS3231 RTC 对象**
DS3231 myRTC;

// **定义时间变量**
byte year, month, date, dow;  // 年、月、日、星期
byte hour, minute, second;    // 时、分、秒

bool century = false;  // 用于跨世纪判断
bool h12Flag;          // 12 小时制标志
bool pmFlag;           // PM 标志(仅用于 12 小时制)

/*****************************************************************************************************
 * **初始化**
 *  - 开启串口和 I2C 通信
 *  - 解释程序的使用方法
 *****************************************************************************************************/
void setup() {
    Serial.begin(57600);  // **初始化串口,波特率 57600**
    Wire.begin();  // **启动 I2C 通信**
    
    // **等待 4 秒,确保 RTC 启动稳定**
    delay(4000);

    // **向用户解释时间格式**
    Serial.println("时间格式:YYMMDDwhhmmssx");
    Serial.println("其中:");
    Serial.println("  YY = 年(如 20 表示 2020 年)");
    Serial.println("  MM = 月(如 04 表示 4 月)");
    Serial.println("  DD = 日期(如 09 表示 9 号)");
    Serial.println("  w  = 星期(1-7,1=星期天,5=星期四)");
    Serial.println("  hh = 24 小时制小时数(如 09 表示上午 9 点,21 表示晚上 9 点)");
    Serial.println("  mm = 分钟(如 02)");
    Serial.println("  ss = 秒(如 42)");
    Serial.println("例如输入:2004095090242x");
    Serial.println("-----------------------------------------------------------------------------");
    Serial.println("请在串口输入时间,并以 'x' 结尾以设置 DS3231 的时间:");
}

/*****************************************************************************************************
 * **主循环**
 *  - 监听串口输入的时间校正数据
 *  - 根据输入设置 DS3231 的时钟
 *  - 在 5 秒内回显 DS3231 时间
 *****************************************************************************************************/
void loop() {
    // **如果串口收到输入数据,则进行时间校正**
    if (Serial.available()) {
        inputDateFromSerial();  // 读取串口数据并解析时间

        myRTC.setClockMode(false);  // **设置 24 小时模式**
        
        // **将输入的时间写入 DS3231**
        myRTC.setYear(year);
        myRTC.setMonth(month);
        myRTC.setDate(date);
        myRTC.setDoW(dow);
        myRTC.setHour(hour);
        myRTC.setMinute(minute);
        myRTC.setSecond(second);

        // **连续 5 秒,每秒打印 DS3231 当前时间**
        for (uint8_t i = 0; i < 5; i++) {
            delay(1000);
            Serial.print(myRTC.getYear(), DEC);
            Serial.print("-");
            Serial.print(myRTC.getMonth(century), DEC);
            Serial.print("-");
            Serial.print(myRTC.getDate(), DEC);
            Serial.print(" ");
            Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC);  // 24 小时制
            Serial.print(":");
            Serial.print(myRTC.getMinute(), DEC);
            Serial.print(":");
            Serial.println(myRTC.getSecond(), DEC);
        }

        // **提示用户输入新时间**
        Serial.println("请在串口输入新的时间,并以 'x' 结尾以设置 DS3231:");
    }
    delay(1000);  // 每秒刷新一次
}

/*****************************************************************************************************
 * **inputDateFromSerial**
 *  - 读取用户串口输入的时间数据
 *  - 解析并存储到全局变量
 *****************************************************************************************************/
void inputDateFromSerial() {
    // **检查串口数据是否完整(结束字符为 'x')**
    boolean isStrComplete = false;
    char inputChar;
    byte temp1, temp2;
    char inputStr[20];  // 存储输入的时间字符串

    uint8_t currentPos = 0;
    while (!isStrComplete) {
        if (Serial.available()) {
            inputChar = Serial.read();
            inputStr[currentPos] = inputChar;
            currentPos += 1;

            // **检查输入是否以 'x' 结尾**
            if (inputChar == 'x') {
                isStrComplete = true;
            }
        }
    }
    Serial.println(inputStr);  // **打印用户输入的数据**

    // **查找字符串中的 'x' 位置**
    int posX = -1;
    for (uint8_t i = 0; i < 20; i++) {
        if (inputStr[i] == 'x') {
            posX = i;
            break;
        }
    }

    // **ASCII 码 '0' 的值(用于转换字符为数字)**
    uint8_t zeroAscii = '0';

    // **解析年**
    temp1 = (byte)inputStr[posX - 13] - zeroAscii;
    temp2 = (byte)inputStr[posX - 12] - zeroAscii;
    year = temp1 * 10 + temp2;

    // **解析月**
    temp1 = (byte)inputStr[posX - 11] - zeroAscii;
    temp2 = (byte)inputStr[posX - 10] - zeroAscii;
    month = temp1 * 10 + temp2;

    // **解析日期**
    temp1 = (byte)inputStr[posX - 9] - zeroAscii;
    temp2 = (byte)inputStr[posX - 8] - zeroAscii;
    date = temp1 * 10 + temp2;

    // **解析星期**
    dow = (byte)inputStr[posX - 7] - zeroAscii;

    // **解析小时**
    temp1 = (byte)inputStr[posX - 6] - zeroAscii;
    temp2 = (byte)inputStr[posX - 5] - zeroAscii;
    hour = temp1 * 10 + temp2;

    // **解析分钟**
    temp1 = (byte)inputStr[posX - 4] - zeroAscii;
    temp2 = (byte)inputStr[posX - 3] - zeroAscii;
    minute = temp1 * 10 + temp2;

    // **解析秒**
    temp1 = (byte)inputStr[posX - 2] - zeroAscii;
    temp2 = (byte)inputStr[posX - 1] - zeroAscii;
    second = temp1 * 10 + temp2;
}

代码简单解读

这段代码使用 DS3231 RTC(实时时钟)模块 通过 I2C 通信 接收用户输入的时间数据,并更新 DS3231 的时钟,核心逻辑如下:

  1. 初始化 RTC
    ✅ DS3231 myRTC; → 创建 DS3231 RTC 对象
    ✅ Wire.begin(); → 启动 I2C 通信
    ✅ Serial.begin(57600); → 初始化串口,波特率 57600

  2. 解释时间格式
    ✅ Serial.println() → 向用户展示输入格式(YYMMDDwhhmmssx)
    ✅ 示例输入 → “2004095090242x” 代表 2020 年 4 月 9 日星期四 09:02:42

  3. 监听串口输入并解析时间
    ✅ inputDateFromSerial(); → 读取串口输入数据并转换为 RTC 兼容格式
    ✅ 解析年、月、日、星期、时、分、秒
    ✅ myRTC.setClockMode(false); → 设置为 24 小时制
    ✅ myRTC.setYear(year); → 设置年份
    ✅ myRTC.setMonth(month); → 设置月份
    ✅ myRTC.setDate(date); → 设置日期
    ✅ myRTC.setDoW(dow); → 设置星期
    ✅ myRTC.setHour(hour); → 设置小时
    ✅ myRTC.setMinute(minute); → 设置分钟
    ✅ myRTC.setSecond(second); → 设置秒

  4. 每 5 秒回显当前时间
    ✅ 每秒打印 DS3231 当前时间,以确保时间正确

  5. 采集间隔
    ✅ delay(1000); → 每秒监听串口输入,等待新时间数据

这段代码让 用户通过串口输入时间,并更新 DS3231 的时钟。

实验串口返回情况

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驴友花雕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值