1 RTC介绍

树莓派为了节约成本以及减小体积,没有板载的实时时钟(real-time clock,RTC),或者叫作硬件时钟。
在某些场合下,如果树莓派无法联网,但是它上面运行的程序又和时间紧密相关,要求系统时间是正确的,在这种情况下,我们就可以为树莓派添加一个外部的RTC,使之重启之后也能保持时间正确。
此实验以DS1302为例

2 DS1302

2.1 模块简介

DS1302模块自带一块CR2032纽扣电池,电池使用时间至少应该有一年以上。
DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:

  • RST复位
  • I/O数据线
  • SCLK串行时钟
    DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。

2.2 模块参数

  • PCB为单面板,尺寸:44mm23mm1.6mm;
  • 带4个定位孔,直径3.1mm;
  • 备用电池为正品天球CR2032,电压3V,电流260mAh,非可充电电池。理论数据保持时间大于10年;
  • 晶振32.768KHz,日本原装进口晶振,匹配电容为6pF,尺寸2*6mm;
  • DS1302为8脚直插国产大芯片,芯片下面有IC座,方便更换及插拔芯片;
  • 模块工作电压兼容3.3V/5V,可与5V及3.3V单片机连接;
  • 工作温度:0°—70°。

2.3 接线

DS1302 树莓派 wiringPi引脚编号
VCC 3.3V输出 3.3V输出
GND Ground(地) Ground(地)
CLK SCLK 14
DAT SDA0 30
RST CEO 10

2.4 寄存器简介

读寄存器地址:81h~8Dh
写寄存器地址:80h~8Ch

2.5 控制字简介

3 代码块

通过对寄存器的操作来读写时间,代码(参考wiringPi自带示例代码)如下:

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<string.h>
#include<time.h>#include<wiringPi.h>//---------------------------------------------------#define    RTC_SECS     0
#define RTC_MINS     1
#define RTC_HOURS    2
#define RTC_DATE     3
#define RTC_MONTH    4
#define RTC_DAY      5
#define RTC_YEAR     6
#define RTC_WP       7
#define RTC_TC       8
#define RTC_BM      31static int dPin, cPin, sPin;
static unsigned int masks[] = { 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0xFF };
/*0x7F 011111110x3F 001111110x1F 000111110x07 000001110xFF 11111111
*///---------------------------------------------------
void ds1302Setup(const int clockPin, const int dataPin, const int csPin);
void ds1302rtcWrite(int reg, unsigned int data);
void ds1302regWrite(const int reg, const unsigned int data);
void dsShiftOut(unsigned int data);
int setLinuxClock();
void ds1302clockRead(int clockdata[8]);
int dsShiftIn();
int bcdToD(unsigned int byte, unsigned int mask);
int setDSClock();
int dToBcd(int tmp);
void ds1302clockWrite(int clock[8]);int main(int argc, char *argv[]) {int i;int clock[8];wiringPiSetup();ds1302Setup(14, 30, 10);if (argc == 2) {if (strcmp(argv[1], "-slc") == 0) {return setLinuxClock();//读取DS1302内的时间来设置Linux的时间}else if (strcmp(argv[1], "-sdsc") == 0) {return setDSClock();//读取Linux的时间来设置DS1302的时间}/*else if (strcmp(argv[1], "-rtest") == 0) {return ramtest();//进行ram测试,此处因为当时觉得没必要所以没有写,具体可以参考wiringPi示例程序}*/else {printf("Usage: ds1302 [-slc | -sdsc | -rtest]\n");return EXIT_FAILURE;}}i = 0;while (true) {printf("%5d: ", i);ds1302clockRead(clock);//读取DS1302内的时间//由于DS1302内的数据是BCD编码,所以需要转化为十进制后才能输出printf(" %2d:%02d:%02d", bcdToD(clock[2], masks[2]), bcdToD(clock[1], masks[1]), bcdToD(clock[0], masks[0]));printf(" %2d/%02d/%04d", bcdToD(clock[3], masks[3]), bcdToD(clock[4], masks[4]), bcdToD(clock[6], masks[6]) + 2000);printf("\n");delay(200);i++;}return 0;
}void ds1302Setup(const int clockPin, const int dataPin, const int csPin) {dPin = dataPin;//30cPin = clockPin;//14sPin = csPin;//10digitalWrite(dPin, LOW);digitalWrite(cPin, LOW);digitalWrite(sPin, LOW);pinMode(dPin, OUTPUT);pinMode(cPin, OUTPUT);pinMode(sPin, OUTPUT);ds1302rtcWrite(RTC_WP, 0);//关闭写保护
}void ds1302rtcWrite(int reg, unsigned int data) {ds1302regWrite(0x80 | ((reg & 0x1f) << 1), data);//将reg转化为写寄存器的实际地址
}void ds1302regWrite(const int reg, const unsigned int data) {digitalWrite(sPin, HIGH);delayMicroseconds(1);dsShiftOut(reg);dsShiftOut(data);digitalWrite(sPin, LOW);delayMicroseconds(1);
}void dsShiftOut(unsigned int data) {pinMode(dPin, OUTPUT);for (int i = 0; i < 8; i++) {digitalWrite(dPin, (data&(1 << i))); delayMicroseconds(1);//LSB优先,从低位开始传输digitalWrite(cPin, HIGH); delayMicroseconds(1);digitalWrite(cPin, LOW); delayMicroseconds(1);}
}int setLinuxClock() {char dateTime[20];char command[64];int clock[8];printf("Setting the Linux Clock from the DS1302... ");fflush(stdout);//冲洗流中的信息ds1302clockRead(clock);// [MMDDhhmm[[CC]YY][.ss]]// 输出格式sprintf(dateTime, "%02d%02d%02d%02d%02d%02d.%02d",bcdToD(clock[RTC_MONTH], masks[RTC_MONTH]),bcdToD(clock[RTC_DATE], masks[RTC_DATE]),bcdToD(clock[RTC_HOURS], masks[RTC_HOURS]),bcdToD(clock[RTC_MINS], masks[RTC_MINS]),20,bcdToD(clock[RTC_YEAR], masks[RTC_YEAR]),bcdToD(clock[RTC_SECS], masks[RTC_SECS]));sprintf(command, "/bin/date %s", dateTime);//字符串格式化system(command);//向Linux输出命令return 0;
}void ds1302clockRead(int clockdata[8]) {int i;unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1);digitalWrite(sPin, HIGH); delayMicroseconds(1);dsShiftOut(regVal);//控制字for (i = 0; i < 8; i++) {clockdata[i] = dsShiftIn();//读取时钟数据//printf("%d %d\n", i, clockdata[i]);}digitalWrite(sPin, LOW); delayMicroseconds(1);
}int dsShiftIn() {uint8_t value = 0;pinMode(dPin, INPUT);delayMicroseconds(1);for (int i = 0; i < 8; i++) {value |= (digitalRead(dPin) << i);digitalWrite(cPin, HIGH); delayMicroseconds(1);digitalWrite(cPin, LOW); delayMicroseconds(1);}return value;
}int bcdToD(unsigned int byte, unsigned int mask) {byte &= mask;int b1 = (byte & 0xF0) >> 4;//取高四位作为十进制的十位数int b2 = byte & 0x0F;//取低四位作为十进制的个位数return b1 * 10 + b2;
}int setDSClock() {struct tm t;//Linux时间结构体time_t now;int clock[8];printf("Setting the clock in the DS1302 from Linux time... ");now = time(NULL);//取得当前时间UTC秒数,无时区转换gmtime_r(&now, &t);//获取当前时间结构,UTC时间,无时区转换//DS1302内数据采用BCD编码,故需转化clock[0] = dToBcd(t.tm_sec);       // secondsclock[1] = dToBcd(t.tm_min);     // minsclock[2] = dToBcd(t.tm_hour);       // hoursclock[3] = dToBcd(t.tm_mday);      // dateclock[4] = dToBcd(t.tm_mon + 1);   // months 0-11 --> 1-12clock[5] = dToBcd(t.tm_wday + 1);   // weekdays (sun 0)clock[6] = dToBcd(t.tm_year - 100); // yearsclock[7] = 0;                      // W-Protect offds1302clockWrite(clock);printf("OK\n");return 0;
}int dToBcd(int tmp) {return ((tmp / 10) << 4) + tmp % 10;
}void ds1302clockWrite(int clock[8]) {unsigned int regVal = 0x80 | ((RTC_BM & 0x1f) << 1);digitalWrite(sPin, HIGH); delayMicroseconds(1);dsShiftOut(regVal);for (int i = 0; i < 8; i++) {dsShiftOut(clock[i]);}digitalWrite(sPin, LOW); delayMicroseconds(1);
}

4 注意之处

  • 如果要使用wiringPi自带的那个示例程序ds1302.c文件,编译命令可用:
    gcc -Wall -o ds1302 ds1302.c -lwiringPi -lwiringPiDev
    -o 表示自命名生成的文件
    -l 表示需要连接到哪些库
  • ds1302内的数据是用BCD编码的,读取和存储都需要先进行转化
  • ds1302是LSB优先的
  • 以上博客有什么问题,请在评论区联系博主

树莓派——实时时钟模块(RTC)相关推荐

  1. 树莓派基础实验32:DS1302实时时钟模块实验

    一.介绍   现在有很多流行的串行时钟芯片,如DS1302,DS1307,PCF8485等,由于简单的接口,低成本和易用性,他们被广泛应用于电话.传真.便携式仪器等产品领域.在本实验中,我们将使用DS ...

  2. 中国实时时钟(RTC)模块市场深度研究分析报告

    [报告篇幅]:113 [报告图表数]:151 [报告出版时间]:2021年9月 报告摘要 2020年中国实时时钟(RTC)模块市场规模达到了 亿元,预计2027年可以达到  亿元,未来几年年复合增长率 ...

  3. 【ESP32】17.DS1302实时时钟模块实验(ThreeWire库 / RtcDS1302库)

    上一篇: [ESP32]16.RFID门禁系统实验(SPI总线 / MFRC522库) 前言: 先放电路连接图: DS1302 RTC模块,内置Tri流充电器的实时时钟(RTC),或Timekeepi ...

  4. ESP32连接DS3231实时时钟(RTC)的方法

    在本篇文章中,我们将学习如何将RTC实时时钟模块DS3231连接到ESP32开发板和0.96英寸I2C OLED显示屏.我们将使用DS3231实时时钟模块跟踪正确的时间和日期,在OLED显示屏上进行显 ...

  5. 实时时钟(RTC)的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

    本文研究全球与中国市场实时时钟(RTC)的发展现状及未来发展趋势,分别从生产和消费的角度分析实时时钟(RTC)的主要生产地区.主要消费地区以及主要的生产商.重点分析全球与中国市场的主要厂商产品特点.产 ...

  6. linux设置rx8010时间,【经验】实时时钟模块RX8010SJ精度的软件校准方法

    RX8010SJ,由于使用简单.标准SOP8封装和高性价比等特点,已经被广泛的应用于各种电子产品的设计中.虽然RX8010SJ内置出厂时经过校准的32.768KHz的晶体单元,能够很大程度上保证了其精 ...

  7. linux下实时时钟芯片(RTC)的读写

    硬件 由于项目的需要在ARM嵌入式板子上挂上了一颗EPSON的RX8010实时时钟芯片,为数据采集提供可靠的时间.RX8010内置了具有温补的晶振,可以简化设计,而且也不贵,所以就选择了它.其实选择其 ...

  8. linux 实时时钟(RTC)驱动【转】

    本文转载自:http://blog.csdn.net/yaozhenguo2006/article/details/6820218 这个是linux内核文档关于rtc实时时钟部分的说明,此文档主要描述 ...

  9. Stm32F103R6之实时时钟(RTC)

    目录 概述 主要特性 读RTC寄存器 配置RTC寄存器 概述 实时时钟是一个独立的定时器.RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能.修改计数器的值可以重新设置系统当前 ...

  10. esp32 rtc 时钟设置不对_「STM32」实时时钟(RTC)实验

    实时时钟的特征和原理 RTCCLK:时钟来源 RTC的时钟有哪些来源呢? 如图,有3个渠道 来自于外部的LSE也就是外部的晶振 来自于HSE的128分频 来自于LSI 一般情况下我们都是采用外部晶振来 ...

最新文章

  1. scikit正则化 API
  2. 干货丨机器学习必知的15大框架
  3. CodeBlcoks插件
  4. python中2个字典比较
  5. python的pandas库中如何计算每列出现最多的值_Python Pandas中根据列的值选取多行数据...
  6. python爬取行业数据_用Python进行Web爬取数据
  7. 用条件运算符编写java程序_Java 编程入门课程丨第 8 单元:条件运算符和控制语句...
  8. 计算机考试可以带首饰吗,高考时不许考生戴框架眼镜?“无声考场”有新规,考生别忽视...
  9. 浏览器端的九种缓存机制介绍
  10. 端到端测试哪家强?不容错过的Cypress
  11. ios程序后台运行设置(不是太懂)
  12. 使用LSTM模型进行产品销售额的预测产品订单效益最大化
  13. centos各文件夹作用
  14. 天气插件平台-天气预报插件-免费天气预报代码—中国天气网
  15. React实现微信公众号支付
  16. java中css js是什么_js、jsp、css都是什么意思?
  17. A Game of Thrones(21)
  18. 深入浅出业务幂等性---4、消息幂等
  19. 在Mac中使用OpenNI
  20. 一般java面试考什么_JAVA面试的时候一般考什么?

热门文章

  1. 【VScode】优雅地将代码打印为 PDF
  2. 【修复版】ONE兔3.0版本社交社区交友婚恋视频即时通讯双端APP原生源码
  3. Eclipse中安装ADT插件
  4. win7创建桌面计算机,win7系统添加或删除虚拟桌面的方法介绍
  5. Excel数据透视表经典教程九《数据透视表计算》
  6. 基于51的光立方制作
  7. java程序设计实用教程 实验6答案_java程序设计实用教程习题解答与实验指导.doc...
  8. Eclipse创建JSP程序
  9. 解析java文件_使用JDK的Parser来解析Java源代码
  10. RS232标准DB9接口定义