当前位置: 首页 > web >正文

单片机获取真实时间的实现方法

单片机获取真实时间(即当前的年月日、时分秒等)通常需要依赖外部时间源或模块,因为单片机本身没有内置的实时时钟(RTC)功能。

在 C 语言环境下,单片机获取真实时间通常需要依赖 外部硬件模块(如 RTC、GPS)或 网络协议(如 NTP)。以下是几种常见方法的详细实现(基于 C 语言,不依赖 Arduino 库):


1. 通过外部 RTC 模块(如 DS3231)

硬件连接
  • 使用 I²C 接口连接 RTC 模块(如 SDA→P1.0, SCL→P1.1)。

  • 为 RTC 模块连接备用电池(如 CR2032)。

C 语言代码示例
#include <stdint.h>
#include "i2c.h"  // 假设已实现 I2C 底层驱动#define DS3231_ADDR 0x68 // DS3231 的 I2C 地址// 从 DS3231 读取时间(BCD 格式)
void ds3231_get_time(uint8_t *sec, uint8_t *min, uint8_t *hour, uint8_t *day, uint8_t *month, uint8_t *year) {uint8_t buf[7];i2c_start();i2c_write(DS3231_ADDR << 1); // 写模式i2c_write(0x00);             // 从寄存器 0 开始读i2c_stop();i2c_start();i2c_write((DS3231_ADDR << 1) | 1); // 读模式for (int i = 0; i < 6; i++) buf[i] = i2c_read(1); // 带 ACKbuf[6] = i2c_read(0);             // 最后一个字节不带 ACKi2c_stop();*sec   = buf[0] & 0x7F; // 去掉最高位(时钟停止标志)*min   = buf[1];*hour  = buf[2];*day   = buf[4];*month = buf[5];*year  = buf[6];
}// BCD 转十进制
uint8_t bcd_to_dec(uint8_t bcd) {return (bcd >> 4) * 10 + (bcd & 0x0F);
}int main() {uint8_t sec, min, hour, day, month, year;ds3231_get_time(&sec, &min, &hour, &day, &month, &year);printf("20%02d-%02d-%02d %02d:%02d:%02d\n",bcd_to_dec(year), bcd_to_dec(month), bcd_to_dec(day),bcd_to_dec(hour), bcd_to_dec(min), bcd_to_dec(sec));return 0;
}

2. 通过网络协议(NTP)获取时间

适用于 ESP8266/ESP32 等带网络功能的单片机。

C 语言代码示例(基于 ESP-IDF)
#include <stdio.h>
#include <time.h>
#include "esp_sntp.h"
#include "esp_wifi.h"
#include "nvs_flash.h"void initialize_sntp() {sntp_setoperatingmode(SNTP_OPMODE_POLL);sntp_setservername(0, "pool.ntp.org");sntp_init();
}void print_local_time() {time_t now;struct tm timeinfo;time(&now);localtime_r(&now, &timeinfo);printf("当前时间: %04d-%02d-%02d %02d:%02d:%02d\n",timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
}void app_main() {nvs_flash_init();wifi_init_sta(); // 假设已实现 WiFi 连接initialize_sntp();while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED) {vTaskDelay(1000 / portTICK_PERIOD_MS);}print_local_time();
}

3. 通过 GPS 模块获取时间

解析 GPS 模块输出的 NMEA 协议(如 $GPRMC 语句)中的 UTC 时间。

C 语言-解析GPRMC语句代码示例
#include <string.h>// 解析 GPRMC 语句中的时间(格式:$GPRMC,hhmmss.ss,A,ddmm.mm,N,...*hh)
void parse_gprmc_time(const char *nmea, uint8_t *hour, uint8_t *min, uint8_t *sec) {char *token = strtok((char *)nmea, ",");for (int i = 0; i < 7; i++) token = strtok(NULL, ","); // 跳过前7字段if (token != NULL && strlen(token) >= 6) {*hour = (token[0] - '0') * 10 + (token[1] - '0');*min  = (token[2] - '0') * 10 + (token[3] - '0');*sec  = (token[4] - '0') * 10 + (token[5] - '0');}
}int main() {const char *gprmc = "$GPRMC,123519.00,A,4807.038,N,01131.000,E,022.4,084.4,230394,,,*6A";uint8_t hour, min, sec;parse_gprmc_time(gprmc, &hour, &min, &sec);printf("UTC 时间: %02d:%02d:%02d\n", hour, min, sec);return 0;
}

GNRMC语句获取时间, 具体实现代码可以参考上篇文章https://blog.csdn.net/kivenx/article/details/147441407?fromshare=blogdetail&sharetype=blogdetail&sharerId=147441407&sharerefer=PC&sharesource=kivenx&sharefrom=from_link


4. 手动设置时间(无外部模块)

如果无需高精度,可通过用户输入或编译时间初始化:

#include <stdio.h>
#include <time.h>void set_manual_time() {struct tm manual_time = {.tm_year = 124,  // 2024 - 1900.tm_mon  = 4,     // 5月(0-based).tm_mday = 1,.tm_hour = 12,.tm_min  = 0,.tm_sec  = 0};time_t t = mktime(&manual_time);printf("手动设置时间: %s", ctime(&t));
}

关键点总结

方法优点缺点适用场景
RTC 模块高精度,掉电不丢失需额外硬件离线设备(如电子钟)
NTP自动同步网络时间依赖网络联网设备(如 IoT)
GPS全球可用,自带定位功耗高,需户外信号车载/户外设备
手动设置无需外部模块不精确,需人工干预调试或简单应用

根据需求选择合适方案,并注意 时区转换 和 数据格式处理(如 BCD 编码)。

http://www.xdnf.cn/news/1350.html

相关文章:

  • Windows 各版本查找计算机 IP 地址指南
  • 在Notepad++中使用NppAtyle插件格式化代码
  • 正则表达式的捕获组
  • 众趣科技X世界读书日丨数字孪生技术赋能图书馆空间智慧化运营
  • TCP四大特性面试回答引导
  • UniOcc:自动驾驶占用预测和预报的统一基准
  • 【华为】防火墙双击热备-之-主备模式-单外网线路
  • MYSQL-库的基本操作
  • 数据结构--AVL树
  • 【问题解决】本机navicat连接云服务器mysql
  • idea无法下载源代码
  • k8s 证书相关问题
  • Python 从PPT文档中提取图片和图片信息(坐标、宽度和高度等)
  • Linux 管道理解
  • 【计算机网络】现代网络技术核心架构与实战解析
  • OCR之身份证识别
  • MinIO 教程:从入门到Spring Boot集成
  • 极狐GitLab 的合并请求部件能干什么?
  • 数据结构-链表
  • OpenGL学习笔记(Blinn-Phong、伽马矫正、阴影)
  • UML2.0中的14种图简介,并借助AI生成UML图
  • 4.23学习总结
  • 【测试报告】幸运闪烁抽奖系统(Java+Selenium+Jmeter自动化测试)
  • 《把握人机共融设计要点,重塑人机协作格局》
  • 如何解决极狐GitLab 合并冲突?
  • 第4天:Linux开发环境搭建
  • 配置Intel Realsense D405驱动与ROS包
  • 配置 Apache 的 HTTPS
  • 一些确保 iPaaS 集成平台与现有系统安全集成的方法
  • 操作系统环境变量