分享一个RX8025T时钟芯片的Arduino代码

news/2024/11/25 19:37:19/

分享一个RX8025T时钟芯片的Arduino代码

背景

之前做那个点阵时钟使用的是DS3231的时钟芯片,这个时钟芯片最大的有点就是高精度,缺点就是有点贵,现在淘宝一颗这样的芯片最便宜的都要十几块钱,大大的增加了我整个点阵时钟的成本造价,所以不得已采用了这个新的时钟芯片方案,就是RX8025T,成本大概就是一块钱左右。

RX8025芯片介绍

1.内置高稳定度的32.768KHz 的 DTCXO (数字温度补偿晶体振荡器)
2. 支持I2C总线的高速模式(400K)。
3. 定时报警功能(可设定:天,日期,小时,分钟)
4. 固定周期定时中断功能。
5. 时间更新中断功能。
6. 32.768KHz频率输出(具有使能OE功能)
7. 闰年自动调整功能。(2000到2099)
8. 宽范围接口电压:2.2V到5.5V
9. 宽范围的时间保持电压:1.8V到5.5V10.低电流功耗:0.8uA/3V (Typ.)

相关文档

更多的介绍看下面的文档,如果文档失效的话,请百度搜索关键字RX-8025T使用说明概要

RX-8025T使用说明概要

电路&PCB设计

其实很早就想搞这个RX8025T的时钟芯片了,但是无奈淘宝上没有现成的模块,所以就只能自己搞一个了,然后就百度各种原理图,发现大家的原理图就都不太一样,所以就综合各种原理图搞一个大概的原理图出来,然后画一个简单的PCB板出来搞一搞,所以原理图这块仅供学习和参考,如果有大佬有更好的方案欢迎在评论区指出。

立创开源地址

RX8025T模块(附Arduino代码)

RX8025T电路原理图

RX8025T电路原理图

PCB-3D预览图

PCB-3D预览图

成品图

成品图

Arduino代码

目前由于我还只擅长Arduino平台的代码处理,所以就只贴出来Arduino的代码,后续如果有其他平台的代码,一定也会在这里列举出来。由于RX8025T主要采用的是I2C通讯协议,且ArduinoI2C的实现较为简单,所以代码也很容易看懂,这里更多的像是搬运别人的代码吧,首先是在网上看到有一段关于8025arduino代码,然后又结合DS3231的代码,由此缝合出来了这段我个人觉得还能用的RX8025T代码。下面列出参考地址:

  • DS3231库源码地址:https://github.com/NorthernWidget/DS3231
  • RX8025参考代码地址:RX8025 library updated for IDE 1.0
  • I2C通讯协议学习地址:RX-8025T使用说明概要

RX8025.h

#ifndef RX8025_h
#define RX8025_h#define RX8025_SEC 0x0
#define RX8025_MIN 0x1
#define RX8025_HR 0x2
#define RX8025_WEEK 0x3
#define RX8025_DATE 0x4
#define RX8025_MTH 0x5
#define RX8025_YR 0x6
#define RX8025_Doffset 0x7
#define RX8025_AW_MIN 0x8
#define RX8025_AW_HR 0x9
#define RX8025_AW_WEEK 0xa
#define RX8025_AD_MIN 0xb
#define RX8025_AD_HR 0xc
#define RX8025_CTL1 0xd
#define RX8025_CTL2 0xE#include <Arduino.h>
#include <Wire.h>
#include <time.h>
// DateTime (get everything at once) from JeeLabs / Adafruit
// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
class DateTime
{
public:DateTime(uint32_t t = 0);DateTime(uint16_t year, uint8_t month, uint8_t day,uint8_t hour = 0, uint8_t min = 0, uint8_t sec = 0);DateTime(const char *date, const char *time);uint16_t year() const{return 2000 + yOff;}uint8_t month() const{return m;}uint8_t day() const{return d;}uint8_t hour() const{return hh;}uint8_t minute() const{return mm;}uint8_t second() const{return ss;}uint8_t dayOfTheWeek() const;// 32-bit times as seconds since 1/1/2000long secondstime() const;// 32-bit times as seconds since 1/1/1970// THE ABOVE COMMENT IS CORRECT FOR LOCAL TIME; TO USE THIS COMMAND TO// OBTAIN TRUE UNIX TIME SINCE EPOCH, YOU MUST CALL THIS COMMAND AFTER// SETTING YOUR CLOCK TO UTCuint32_t unixtime(void) const;protected:uint8_t yOff, m, d, hh, mm, ss;
};//判断年份是否是闰年
bool isleapYear(const uint8_t);class RX8025
{
private:unsigned char RX8025_Control[2];/*** 获取寄存器数据* @return byte*/byte getData(byte regaddr);/*** @brief 将十进制编码的二进制数转换为普通十进制数** @param val* @return byte*/byte decToBcd(byte val);/*** 将二进制编码的十进制数转换为普通十进制数* @param val* @return byte*/byte bcdToDec(byte val);public:RX8025(); // costruttore/*** 初始化*/void RX8025_init(void);/*** 向时钟芯片设置时间* @param s  秒钟* @param m  分钟* @param h 时钟* @param d  天* @param mh 月* @param y 年*/void setRtcTime(uint8_t s, uint8_t m, uint8_t h, uint8_t d, uint8_t mh, uint8_t y);/*** 获取秒钟*/byte getSecond();/*** 获取分钟数* @return byte*/byte getMinute();/*** 获取小时数* @return byte*/byte getHour();/*** 获取星期数* @return byte*/byte getDoW();/*** 获取日期* @return byte*/byte getDate();/*** 获取月份* @return byte*/byte getMonth();/*** 获取年份* @return byte*/byte getYear();/*** 获取时间戳* @return long*/long getUnixtime();
};#endif

RX8025.cpp


#include "RX8025.h"
// These included for the DateTime class inclusion; will try to find a way to
// not need them in the future...
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#endif
// Changed the following to work on 1.0
//#include "WProgram.h"
#include <Arduino.h>// 8025I2C地址
#define RX8025_address 0x32
// 日期起始时间(这里为啥要减掉八个小时,因为用的日期所在时区和国内时区相差8小时,所以需要减掉八小时的时区时间)
#define SECONDS_FROM_1970_TO_2000 946684800 - (8 * 60 * 60)
//
static const uint8_t daysInMonth[] PROGMEM = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};/**自2000/01/01起的天数,2001年有效。。2099
*/
static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d)
{if (y >= 2000)y -= 2000;uint16_t days = d;for (uint8_t i = 1; i < m; ++i)days += pgm_read_byte(daysInMonth + i - 1);if (m > 2 && isleapYear(y))++days;return days + 365 * y + (y + 3) / 4 - 1;
}static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s)
{return ((days * 24L + h) * 60 + m) * 60 + s;
}DateTime::DateTime(uint32_t t)
{t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970ss = t % 60;t /= 60;mm = t % 60;t /= 60;hh = t % 24;uint16_t days = t / 24;uint8_t leap;for (yOff = 0;; ++yOff){leap = isleapYear(yOff);if (days < 365 + leap)break;days -= 365 + leap;}for (m = 1;; ++m){uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1);if (leap && m == 2)++daysPerMonth;if (days < daysPerMonth)break;days -= daysPerMonth;}d = days + 1;
}DateTime::DateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
{if (year >= 2000){year -= 2000;}yOff = year;m = month;d = day;hh = hour;mm = min;ss = sec;
}// supported formats are date "Mmm dd yyyy" and time "hh:mm:ss" (same as __DATE__ and __TIME__)
DateTime::DateTime(const char *date, const char *time)
{static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";static char buff[4] = {'0', '0', '0', '0'};int y;sscanf(date, "%s %c %d", buff, &d, &y);yOff = y >= 2000 ? y - 2000 : y;m = (strstr(month_names, buff) - month_names) / 3 + 1;sscanf(time, "%c:%c:%c", &hh, &mm, &ss);
}// UNIX time: IS CORRECT ONLY WHEN SET TO UTC!!!
uint32_t DateTime::unixtime(void) const
{uint32_t t;uint16_t days = date2days(yOff, m, d);t = time2long(days, hh, mm, ss);t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000return t;
}// Slightly modified from JeeLabs / Ladyada
// Get all date/time at once to avoid rollover (e.g., minute/second don't match)
static uint8_t bcd2bin(uint8_t val)
{return val - 6 * (val >> 4);
}
// Commented to avoid compiler warnings, but keeping in case we want this
// eventually
static uint8_t bin2bcd(uint8_t val) { return val + 6 * (val / 10); }/**判断是否是闰年
*/
bool isleapYear(const uint8_t y)
{//检查是否可以被4整除if (y & 3){return false;}// 仅在第一次失败时检查其他return (y % 100 || y % 400 == 0);
}RX8025::RX8025() // costruttore
{RX8025_Control[0] = 0x20;RX8025_Control[1] = 0x00;
}/*** 向时钟芯片设置时间* @param s  秒钟* @param m  分钟* @param h 时钟* @param d  天* @param mh 月* @param y 年*/
void RX8025::setRtcTime(uint8_t s, uint8_t m, uint8_t h, uint8_t d, uint8_t mh, uint8_t y)
{// 使用指定的地址开始向I2C从设备进行传输。Wire.beginTransmission(RX8025_address);Wire.write((byte)0x00);Wire.write(decToBcd(s));Wire.write(decToBcd(m));Wire.write(decToBcd(h));Wire.write(0x1);Wire.write(decToBcd(d));Wire.write(decToBcd(mh));Wire.write(decToBcd(y));// 停止与从机的数据传输Wire.endTransmission();
}/*** 获取寄存器里面的数据* @param regaddr* @return byte*/
byte RX8025::getData(byte regaddr)
{// 使用指定的地址开始向I2C从设备进行传输。Wire.beginTransmission(RX8025_address);Wire.write(regaddr);// 停止与从机的数据传输Wire.endTransmission();// 由主设备用来向从设备请求字节。Wire.requestFrom(RX8025_address, 1);// 读取数据return Wire.read();
}/*** @brief 初始化函数**/
void RX8025::RX8025_init(void)
{// Wire初始化Wire.begin();// 使用指定的地址开始向I2C从设备进行传输。Wire.beginTransmission(RX8025_address);Wire.write(0xe0);for (unsigned char i = 0; i < 2; i++){Wire.write(RX8025_Control[i]);}// 使用指定的地址开始向I2C从设备进行传输。Wire.endTransmission();
}/*** @brief 将十进制编码的二进制数转换为普通十进制数** @param val* @return byte*/
byte RX8025::decToBcd(byte val)
{// 将十进制编码的二进制数转换为普通十进制数return ((val / 10 * 16) + (val % 10));
}/*** 将二进制编码的十进制数转换为普通十进制数** @param val* @return byte*/
byte RX8025::bcdToDec(byte val)
{// 将二进制编码的十进制数转换为普通十进制数return ((val / 16 * 10) + (val % 16));
}/*** 获取秒钟*/
byte RX8025::getSecond()
{byte buff = getData(RX8025_SEC);return bcdToDec(buff & 0x7f);
}/*** 获取分钟数* @return byte*/
byte RX8025::getMinute()
{byte buff = getData(RX8025_MIN);return bcdToDec(buff & 0x7f);
}/*** 获取小时数* @return byte*/
byte RX8025::getHour()
{byte buff = getData(RX8025_HR);return bcdToDec(buff & 0x3f);
}/*** 获取星期数* @return byte*/
byte RX8025::getDoW()
{byte buff = getData(RX8025_WEEK);return bcdToDec(buff & 0x07);
}/*** 获取日期* @return byte*/
byte RX8025::getDate()
{byte buff = getData(RX8025_DATE);return bcdToDec(buff & 0x3f);
}/*** 获取月份* @return byte*/
byte RX8025::getMonth()
{byte buff = getData(RX8025_MTH);return bcdToDec(buff & 0x1f);
}/*** 获取年份* @return byte*/
byte RX8025::getYear()
{byte buff = getData(RX8025_YR);return bcdToDec(buff & 0xff);
}long RX8025::getUnixtime()
{// 使用指定的地址开始向I2C从设备进行传输。Wire.beginTransmission(RX8025_address);Wire.write(0x00);// 停止与从机的数据传输Wire.endTransmission();// 由主设备用来向从设备请求字节。Wire.requestFrom(RX8025_address, 7);// 读取数据uint16_t ss = bcdToDec(Wire.read() & 0x7F);uint16_t mm = bcdToDec(Wire.read() & 0x7f);uint16_t hh = bcdToDec(Wire.read() & 0x3f);Wire.read();uint16_t d = bcdToDec(Wire.read() & 0x3f);uint16_t m = bcdToDec(Wire.read() & 0x1f);uint16_t y = bcdToDec(Wire.read() & 0xff) + 2000;return DateTime(y, m, d, hh, mm, ss).unixtime();
}

主函数

#include "Arduino.h"
#include "RX8025.h"RX8025 rtc;
DateTime datetime;void setup(void)
{Serial.begin(9600);Serial.println("on the setup");rtc.RX8025_init();rtc.setRtcTime(0, 24, 21, 4, 4, 22);
}void loop(void)
{Serial.print(rtc.getYear());Serial.print("年");Serial.print(rtc.getMonth());Serial.print("月");Serial.print(rtc.getDate());Serial.print("日");Serial.print(rtc.getHour());Serial.print(":");Serial.print(rtc.getMinute());Serial.print(":");Serial.println(rtc.getSecond());delay(1000);Serial.println(rtc.getUnixtime());
}

参考文章

I2C详解

太极创客 - Arduino – Wire 库

RX-8025T使用说明概要

RX8025 library updated for IDE 1.0


http://www.ppmy.cn/news/112507.html

相关文章

4rx4 服务器内存2rx4_服务器内存条上写8GB,2RX4,其中2RX4是什么意思?是单条8G的。...

展开全部 其实62616964757a686964616fe58685e5aeb931333365663535这个是内存计算方法,有个前提是根据CPU的关系。 1、CPU数据总线的位宽,现在一般是64bit,这个位宽就称之为物理Bank。 2、那么memory 1RX4则表示1个64bit,X4则表示memory每颗内存颗粒的位数。 从这里我们就可…

[RK3288][Android6.0] RTC模块RX8010SJ驱动添加及改动

Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 设备部分驱动部分改动部分参考 在网上的其他branch上找到一份RX8010SJ的驱动&#xff0c;但是有点问题&#xff0c;先贴代码&#xff0c;再说明修改部分。 设备部分&#xff1a; 比较简单&#xff0c;确定I2C端口以及…

linux中的rx作用,linux – ifconfig输出中RX’错误’和’帧’的确切含义?

我看到(RHEL)节点出现网络问题(数据包丢失),这似乎也表现为ifconfig输出中’error’和’frame’字段的非零计数&#xff1a; eth2 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx ... RX packets:277593775 errors:1049 dropped:0 overruns:0 frame:536 在某处有详细描述’错误…

PCIe_TX/RX测试步骤

TX测试 一: GEN1、2、3采用自动化测试&#xff1a; 1. 点击infinum软件中Analyze->Automated Test Apps->D9050PCIC PCIExpress Gen5 Test App&#xff0c;进入自动化测试界面&#xff1b; 2. Set Up窗口&#xff1a;PCIE5.0->CEM-End Point Tests->Device Defi…

摄影小白入门相机选择(个人出发)

1.微单与卡片机 在产品质量上&#xff0c;相机的感光器件CMOS这些&#xff0c;可以一概认为&#xff0c;同价同质。 两者的区别主要在镜头的设计&#xff0c;黑卡被设计为不可更换镜头式无反相机&#xff0c;入门级别的一般搭配标准变焦镜头 如16-55这种焦距&#xff0c;旗舰级…

无线路由器wifi TX/RX率和实际吞吐量的区别

无意中发现无线路由器中 wifi TX/RX率都超过100M bit/s&#xff0c;但是电脑实际上10M bit/s都没有。网上查到两个解释&#xff1a; “The TX/RX rate is the rate that "the radios talk to each other" ! It is NOT the same as the speed of the data (Etherne…

dpdk 问题分析:ice 100G 网卡 rx_packets 与 rx_bytes 统计问题

问题描述 1. ipackets 减掉 imissed 统计的问题 ice 100G 网卡获取的 ipackets 会减掉 imissed 的报文&#xff0c;此时统计的是软件实际从网卡收包的 pps&#xff0c;但收包的 bps 中没有减掉这部分报文长度且硬件不能提供这部分信息用于计算&#xff0c;为此屏蔽 ipackets …

索尼rx1r人脸识别_RX1 vs RX1R 索尼黑卡新老机皇画面解析力内战

现在的相机市场开始往微单的方向转移,以往的卡片机市场开始缩小,但却开始往高端卡片机发展了。索尼的RX1就是这样一款一体化全幅数码相机,时隔半年,RX1的小改款RX1R也跟着登场。两者在硬件配置上没有什么不同,不过,两者的成像是否也完全一致呢?日本媒体近日对两台机器进…