5

我有一个 DS3231 RTC 模块,我正在尝试使用我的 Arduino UNO 通过 I2C 读取它的时间。我正在使用库提供的示例代码,但它似乎不起作用。

我从串行监视器中得到的唯一结果是:

20165-85-165 25:165:165 Temperature=254

我对另一个 RTC 模块也得到了同样的结果,我的猜测(可能不是真的)是它们可能已经溢出,尽管似乎没有复位引脚。

#include <DS3231.h>
#include <Wire.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;

byte year, month, date, DoW, hour, minute, second;

void setup() {
    // Start the I2C interface
    Wire.begin();
  #define oneTime
  #ifdef oneTime
    Clock.setSecond(50);//Set the second 
    Clock.setMinute(59);//Set the minute 
    Clock.setHour(11);  //Set the hour 
    Clock.setDoW(5);    //Set the day of the week
    Clock.setDate(31);  //Set the date of the month
    Clock.setMonth(5);  //Set the month of the year
    Clock.setYear(13);  //Set the year (Last two digits of the year)
  #endif
        // Start the serial interface
    Serial.begin(115200);

}
void ReadDS3231()
{
  int second,minute,hour,date,month,year,temperature; 
  second=Clock.getSecond();
  minute=Clock.getMinute();
  hour=Clock.getHour(h12, PM);
  date=Clock.getDate();
  month=Clock.getMonth(Century);
  year=Clock.getYear();

  temperature=Clock.getTemperature();

  Serial.print("20");
  Serial.print(year,DEC);
  Serial.print('-');
  Serial.print(month,DEC);
  Serial.print('-');
  Serial.print(date,DEC);
  Serial.print(' ');
  Serial.print(hour,DEC);
  Serial.print(':');
  Serial.print(minute,DEC);
  Serial.print(':');
  Serial.print(second,DEC);
  Serial.print('\n');
  Serial.print("Temperature=");
  Serial.print(temperature); 
  Serial.print('\n');
}
void loop() {ReadDS3231();delay(1000);}
4

4 回答 4

3

这里有同样的问题,结果表明 DS3231 通信可能由于不同的事件而与微控制器不同步。似乎神秘的输出来自于此,至少在这里使用连接到 ESP8266 Arduino 的 DS3231 进行调试。

遵循数据表规范:

只要 VCC 或 VBAT 处于有效电平,就可以访问 I2C 接口。如果连接到 DS3231 的微控制器由于 VCC 丢失或其他事件而复位,则微控制器和 DS3231 I2C 通信可能会变得不同步,例如,微控制器在从 DS3231 读取数据时复位。当微控制器复位时,可以通过切换 SCL 将 DS3231 I2C 接口置于已知状态,直到观察到 SDA 处于高电平。此时,微控制器应在 SCL 为高时将 SDA 拉低,从而产生 START 条件。

并从他们的官方应用笔记 3506中获得灵感

使用 ESP8266 并使用他们的I2C 实现。您可以获得有关如何按位访问 SDA 和 SCL 引脚的宏功能。这是基于8051 的官方示例实现的一种重置功能。

#define SDA_LOW()   (GPES = (1 << SDA))
#define SDA_HIGH()  (GPEC = (1 << SDA)) 
#define SCL_LOW()   (GPES = (1 << SCL))
#define SCL_HIGH()  (GPEC = (1 << SCL))
#define SDA_READ()  ((GPI & (1 << SDA)) != 0)

void resetRTC() {

  pinMode(SDA, INPUT_PULLUP);
  pinMode(SCL, INPUT_PULLUP);
  do {
    SDA_HIGH();
    SCL_HIGH();
    if (SDA_READ()) {
      SDA_LOW();
      SDA_HIGH();
    }
    SCL_LOW();
  } while (SDA_READ() == 0);

}

这工作正常,似乎可以解决问题

一个更简单的解决方案是调用Wire.status(),它似乎也有效。

Wire.status();

我不确定是否适用于所有情况。此方法正在检查状态,并在它调用的一种情况下twi_write_start()与上述函数有一些相似之处resetRTC()

如果您想为 ATMEL Arduino 实现类似的功能,您需要研究按位实现以在Arduino I2C 内核上操作 SDA 和 SCL。

于 2017-10-31T04:11:11.153 回答
1

对于遇到此问题的任何人,只需尝试更换电池即可。

我买了一个新的 DS3231 模块,它从零开始就无法工作。我得到奇怪的数据和温度为零。当我设法正确读取日期时,它没有保留。我尝试了所有我能找到的图书馆,但都是徒劳的。

我更换了电池,现在一切正常。

于 2016-07-01T09:53:05.613 回答
0

你把它连接到什么引脚?在我将 RTC 的 SDA 和 SCL 分别连接到 Arduino 的 SDA 和 SCL 之前,我遇到了同样的问题。根据型号的不同,这些是 Mega2560 上的引脚 20 和 21,Micro 上的引脚 19 和 18。

于 2017-03-02T20:02:43.303 回答
-3

使用:Serial.begin(9600); / 另一个波特率而不是 Serial.begin(115200);

于 2016-01-23T04:35:01.243 回答