DS3231 中断引脚问题

仍然使用之前提到的模块 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));
    }

  }

}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注