我无法让 DS3231 RTC 工作

I can't get DS3231 RTC to work

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

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

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);}

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

对于遇到此问题的任何人,请尝试更换电池。

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

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

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

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

遵循 datasheet 规范:

The I2C interface is accessible whenever either VCC or VBAT is at a valid level. If a microcontroller connected to the DS3231 resets because of a loss of VCC or other event, it is possible that the microcontroller and DS3231 I2C communications could become unsynchronized, e.g., the microcontroller resets while reading data from the DS3231. When the microcontroller resets, the DS3231 I2C interface may be placed into a known state by toggling SCL until SDA is observed to be at a high level. At that point the microcontroller should pull SDA low while SCL is high, generating a START condition.

并启发了他们的官方application note 3506

使用 ESP8266 并使用他们的 I2C implementation. You can get macros functions on how to access the SDA and SCL pins bitwise. Here is one implemented reset function based on the official example for the 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 core.

上操作 SDA 和 SCL