仍然使用之前提到的模块 https://www.lab-z.com/ds3231165/ 。这个模块已经有内部上拉了,因此中断 Pin 无需再额外上拉。
这次遇到的问题是中断经常触发,打开Alarm1 后就立即触发。经过研究发现这是因为没有清除A1F 导致的,之前触发过Alarm1 中断后这个Flag 就会一直处于 1(触发状态)。当再次Enable Alarm1 后,就会继续拉低 Interrupt

解决方法是在关闭 Alarm 1的时候多做一个动作:
// 特别注意必须用下面函数清除 Interrupt Flag 否则只要 Enable Alarm 就会触发
myRTC.checkIfAlarm(1);
// 关闭 Alarm1
myRTC.turnOffAlarm(1);
完整的测试代码如下:
#include <Wire.h>
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DS3231.h>
DS3231 myRTC;
RTClib CurrentTime;
WiFiMulti wifiMulti;
JsonDocument doc;
const char* ssid = "CMCC-TSR6739";
const char* password = "!!1783az";
void showdate() {
bool century;
bool h12Flag;
bool pmFlag;
Serial.print(myRTC.getYear(), DEC);
Serial.print("-");
Serial.print(myRTC.getMonth(century), DEC);
Serial.print("-");
Serial.print(myRTC.getDate(), DEC);
Serial.print(" ");
Serial.print(myRTC.getDoW(), DEC);
Serial.print(" ");
Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC); //24-hr
Serial.print(":");
Serial.print(myRTC.getMinute(), DEC);
Serial.print(":");
Serial.println(myRTC.getSecond(), DEC);
}
void setup() {
wifiMulti.addAP(ssid, password);
Serial.begin(115200);
Serial.println("Start");
Wire.begin();
delay(100);
myRTC.setClockMode(false); // set to 24h
pinMode(14, INPUT_PULLUP);
}
// 设置 seconds 秒后的闹钟
void SetAlart(uint32_t seconds) {
DateTime Current = CurrentTime.now();
printf("%d\n", Current.unixtime());
printf("%d %d %d %d %d %d \n",
Current.year(), Current.month(), Current.day(),
Current.hour(), Current.minute(), Current.second());
Current = DateTime(Current.unixtime() + seconds);
printf("%d\n", Current.unixtime());
printf("%d %d %d %d %d %d \n",
Current.year(), Current.month(), Current.day(),
Current.hour(), Current.minute(), Current.second());
// 1分钟后触发
myRTC.setA1Time(Current.day(), Current.hour(), Current.minute(), Current.second(), 0, false, false, false);
// myRTC.setA1Time(Current.day(), Current.hour(), Current.minute(), Current.second()+20, 0, false, false, false);
// 打开闹钟
myRTC.turnOnAlarm(1);
}
uint8_t geti2c(uint8_t reg) {
Wire.beginTransmission(0x68);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(0x68, 1);
return Wire.read();
}
unsigned long char_to_uint32(const char* t) {
unsigned long result = 0;
for (int i = 0; i < 14; i++) {
if (t[i] >= '0' && t[i] <= '9') {
result = result * 10 + (t[i] - '0');
}
}
result = result + 8 * 3600;
return result;
}
void loop() {
while (Serial.available()) {
char c = Serial.read();
if (c == '1') {
// 从互联网取得当前时间
Serial.print("测试:从互联网获得当前时间, 并且设置给 RTC:");
// 从互联网取得时间
if ((wifiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
//http.begin("http://quan.suning.com/getSysTime.do"); //HTTP
http.begin("http://api.k780.com/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json");
int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) {
String payload = http.getString();
// 解析JSON数据
DeserializationError error = deserializeJson(doc, payload);
Serial.println(doc["result"]["timestamp"].as<const char*>());
myRTC.adjust(char_to_uint32(doc["result"]["timestamp"].as<const char*>()));
} else {
Serial.println("Http 访问出错");
}
http.end();
} else {
Serial.println("WIFI 未连接");
}
Serial.print("测试结束");
}
if (c == '2') {
// 显示当前时间
showdate();
}
if (c == '3') {
// 设置 20秒后触发中断,对应引脚会变低
SetAlart(20);
}
if (c == '4') {
// 关闭闹钟
Serial.println("TurnOff Alarm");
// 特别注意必须用下面函数清除 Interrupt Flag 否则只要 Enable Alarm 就会触发
myRTC.checkIfAlarm(1);
// 关闭 Alarm1
myRTC.turnOffAlarm(1);
}
if (c == '5') {
// 检查闹钟状态
if (myRTC.checkAlarmEnabled(1)) {
Serial.println("闹钟 Enabled");
if (myRTC.checkIfAlarm(1, false)) {
Serial.println("闹钟已触发");
} else {
Serial.println("闹钟未触发");
}
} else {
Serial.println("闹钟 Disabled");
}
}
if (c == '6') {
// 输出当前闹钟设定的时间
byte alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits;
bool alarmDy, alarmH12Flag, alarmPmFlag;
// Display Alarm 1 information
myRTC.getA1Time(alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits, alarmDy, alarmH12Flag, alarmPmFlag);
Serial.print(alarmDay, DEC);
if (alarmDy) {
Serial.print(" DoW");
} else {
Serial.print(" Date");
}
Serial.print(' ');
Serial.print(alarmHour, DEC);
Serial.print(' ');
Serial.print(alarmMinute, DEC);
Serial.print(' ');
Serial.print(alarmSecond, DEC);
Serial.print(' ');
if (alarmH12Flag) {
if (alarmPmFlag) {
Serial.print("pm ");
} else {
Serial.print("am ");
}
}
Serial.printf("alarmBits:%x %x \n", alarmBits, alarmDy);
Serial.println(' ');
}
if (c == '7') {
// 寄存器检测
printf("0x07: %d\n", geti2c(0x07));
printf("0x08: %d\n", geti2c(0x08));
printf("0x09: %d\n", geti2c(0x09));
printf("0x0A: %d\n", geti2c(0x0A));
printf("0x0E: %d\n", geti2c(0x0E));
printf("0x0F: %d\n", geti2c(0x0F));
}
}
}