Ist es die richtige Verwendung des RTC RV8523, um einen atmega328p aufzuwecken?

Ich verwende den RV8523, um alle 2 Minuten einen Arduino atmega328p aufzuwecken. Die RTC ist wie folgt verkabelt:

Schema der mit dem ATmega328p verdrahteten RTC

Wobei INT1 mit Port D Pin 3 verdrahtet ist. Der interne Pull-up-Widerstand ist aktiviert und funktioniert dennoch ordnungsgemäß. Es wacht manchmal alle 2 Minuten auf, manchmal aber nicht.

Es gibt den Code zum Programmieren der RTC:

#define I2C_ADDR (0xD0 >> 1)

#define TIMERA_CLK 0x03    
#define TIMERA_PERIOD 0x02

void Rtc_init()
{
    Wire.beginTransmission(I2C_ADDR);
    Wire.write(byte(0x00)); //control 1 register
    Wire.write(byte(0x00)); 
    Wire.endTransmission();

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(byte(0x01)); //control 2 register
    Wire.write(byte(0x02)); 
    Wire.endTransmission();

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(byte(0x02)); //control 3 register
    Wire.write(byte(0x00)); 
    Wire.endTransmission();

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(byte(0x10));       // Timer A Clock register
    Wire.write(byte(TIMERA_CLK)); //  
    Wire.endTransmission();

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(byte(0x11));          // Timer A register
    Wire.write(byte(TIMERA_PERIOD)); //  
    Wire.endTransmission();

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(byte(0x0F)); // Timer & Clkout register
    Wire.write(byte(0xBA)); //  
    Wire.endTransmission();

    pinMode(INT, INPUT_PULLUP); // <== Sleep mode from RTC

    delay(100);
}

UND da ist der "Haupt"-Code:

#define INT 1
void setup()
{

    Serial.begin(9600);
    while (!Serial){;}

    mySerial.begin(9600);


    mySerial.println("Start ");


    // Setup RTC
    Rtc_init();
    mySerial.println("RTC Init Done");

}

void loop () 
{
    mySerial.println("\n\nWAKE UP ");
    delay(1000);
    mySerial.println("\n\nGoing to sleep");
    mySerial.flush(); 


    attachInterrupt(INT, Push, FALLING); 
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(INT); 
}

void Push()
{

}

Alle Bibliotheken sind enthalten und es gibt das Signal vom RTC-Unterbrechungsstift (INT1):RTC-Signal ==> INT1.  Wir können die Unterbrechung sehen, aber die Spannung scheint sehr niedrig zu sein.

Wenn Sie einen Hinweis haben, um mich in die richtige Richtung zum Debuggen zu führen, habe ich keine Ideen mehr :-/

BEARBEITEN: Ich sollte präzisieren, dass der Atmega genau wie die RTC mit einer Spannung von 3,3 V betrieben wird. BEARBEITEN 2: Das auf dem Oszilloskop sichtbare Signal wird alle 2 Minuten 1 Mal korrekt wiederholt, ABER der Atmega wacht nicht auf:Auf einer größeren zeitlichen Skala: Wir können sehen, wie sich das Muster alle 2 Minuten wiederholt

Ich würde zunächst überprüfen, ob dieser Impuls lang genug ist, um von der MCU erkannt zu werden.
Ich glaube schon ! Tatsächlich wacht der Atmega manchmal auf und ich habe überprüft, dass das Signal direkt bei 0 V liegt. Dort ist dies nicht der Fall (das Minimum liegt bei 18 mV), daher hängt es meiner Meinung nach eher mit dem Spannungspegel als mit dem Impulszeitpunkt zusammen. Ich werde das Atmega-Datenblatt überprüfen, nur um sicherzugehen.
Nach kurzer Überprüfung kann ich nur sagen, dass die Pulsdauer 15ms beträgt. Ich habe im atmega328p-Datenblatt keine Informationen darüber gefunden. Wie gesagt, ich bin mir ziemlich sicher, dass es kein Timing-Problem ist.
Ich fand heraus: "Impulse, die länger als eine Taktperiode dauern, erzeugen einen Interrupt". Ich verwende einen externen Oszillator mit 8 MHz, sodass die Taktperiode 0,125 us beträgt (nicht sicher) und die Impulsdauer etwa 15 ms beträgt. Ich denke wirklich, dass das hier nicht das Problem ist :-/
Das obige Zitat gilt für den normalen Betrieb. Hier ist die, die Sie brauchen: "Hinweis: Wenn ein durch einen Pegel ausgelöster Interrupt zum Aufwachen aus dem Ausschalten verwendet wird, muss der erforderliche Pegel lange genug gehalten werden, damit die MCU das Aufwecken abschließen kann, um den Pegel-Interrupt auszulösen."
Ich frage mich, warum verwenden Sie überhaupt eine externe Uhr? Das „P“ in 328P steht für „Pico Power“, ein umfangreiches Set an Funktionen zum Energiesparen. Tatsächlich stützt sich die von Ihnen verwendete Arduino-Bibliothek auf diese Funktionen. Bedeutung - Wenn Sie die MCU so ausschalten, wie Sie es tun, geht sie in einen Zustand, der es ihr ermöglicht , nach einer voreingestellten Zeit von selbst aufzuwachen . Das Hinzufügen von RV8523 erhöht nur den Stromverbrauch, wie gering er auch sein mag
Und noch etwas, laut Datenblatt kann nur der Level-Interrupt zum Aufwecken durch INT0/1 verwendet werden. Ich glaube, Sie verwenden Level Change Interrupt in Ihrem Code.
Ich dachte, es wäre aus zwei Gründen eine gute Idee, eine externe RTC zu verwenden: Einer ist, weil die von mir verwendete Low-Power-Bibliothek es ermöglicht, den atmega328p für maximal 8 Sekunden oder für immer in den Tiefschlaf zu versetzen (ich brauche 2 Minuten). Der zweite Grund ist, sicherzustellen, dass die Uhr erhalten bleibt, selbst wenn die Batterie schwach wird (unter Verwendung der Backup-Batterie der RTC). Außerdem habe ich irgendwo gelesen, dass diese externe RTC genauer ist als die im atmega328p (aber vielleicht irre ich mich).
Wo haben Sie die Informationen herausgefunden, die besagen, dass wir die fallende Flanke nicht verwenden können, um den ATmega aufzuwecken? Wie auch immer, danke für deine Hilfe, es ist sehr nützlich!
Vielen Dank, vielleicht löst es mein Problem! Ich werde dies versuchen und zurückkommen, um es zu bestätigen
Ich denke immer noch, dass die Länge des Pulses auch zum Problem beiträgt. Der Aufwach-Interrupt erfordert, dass der Eingang während der gesamten Aufwachzeit, die bis zu 258 Taktzyklen lang sein kann, niedrig ist. Die MCU wacht möglicherweise immer noch auf, aber es wird kein Interrupt generiert, und ich weiß nicht, wie Ihre Bibliothek damit umgehen wird. Zur Präzision: Es ist nur so gut wie die Taktquelle. Sie können genau den gleichen (oder besseren) 32,768-kHz-Quarz wie in RV8523 an MCU-TOSC-Pins anschließen.
Ich habe versucht, die geebnete Unterbrechung anstelle der gepulsten zu verwenden, und es hat funktioniert! Ich danke Ihnen für Ihre Hilfe. Wenn Sie sagen, ich sollte einen externen Kristall verwenden, meinen Sie, ich könnte ihn mit einem internen Timer oder etwas verwenden, um die MCU aufzuwecken? Hier verwende ich den RV8523 nur zum Erzeugen von Interrupts, ich verwende ihn nicht als Taktgeber für die MCU.
Froh, dass ich helfen konnte. Ich werde dann eine Antwort geben. Was ich über Kristall gesagt habe, ist, dass Ihre MCU 2 davon unterstützt, eine für die Prozessoruhr, eine 32,768 für den internen Timer, was sie genauso genau macht wie RV8523. Wenn Sie sich also jemals entscheiden, den internen MCU-Timer zum Aufwachen zu verwenden, werden Sie nicht an Präzision verlieren.
ah okay, gut zu wissen! Mein einziges Argument für die Verwendung dieser RTC ist also, dass ich mehr als 8 Sekunden im Tiefschlaf tun kann.
Nun, die Schaltpläne sind einfach, der hinzugefügte Strom ist winzig und die Bequemlichkeit beim Einstellen der Verzögerung ist vorhanden. Ich sehe keinen Grund, es nicht zu verwenden, außer meiner eigenen (also nicht auf Ihren Fall anwendbaren) Abneigung gegen sogar einen einzelnen Widerstand, der der Schaltung hinzugefügt wird, wenn dies vermieden werden kann. Ich werde der Antwort einige Gedanken zu diesem 8-Sekunden-Limit hinzufügen.
Irgendwie stellte sich heraus, dass das Update fünfmal länger war als die eigentliche Antwort ... Und ich denke, die Formulierung über 2 Kristalle war irreführend. Sie können nicht gleichzeitig verbunden werden, es ist entweder Uhrenquarz oder Systemuhrquarz.

Antworten (1)

Zum Aufwecken durch INT0/1 kann nur der Pegel-Interrupt verwendet werden. Pegelwechsel-Interrupt funktioniert nicht.

Wenn außerdem ein Interrupt verarbeitet werden muss (nicht nur aufwachen), dann sollte es während der gesamten Aufwachzeit, die bis zu 258 Taktzyklen lang sein kann, niedrig gehalten werden. Andernfalls wacht die MCU auf, aber der Interrupt geht verloren.

AKTUALISIEREN

Bezieht sich nicht direkt auf die Frage, könnte aber eine Überlegung wert sein.

Die 8-Sekunden-Grenze für die Schlafverzögerung, die Sie dazu zwang, einen externen Timer zu verwenden, ist rein künstlich. Es ist ein direktes Ergebnis der Bibliothek, die Sie verwenden, indem Sie sich auf den Watchdog-Timer als Wake-Up-Interrupt-Quelle verlassen. Der Grund, warum sie Watchdog verwenden, ist, dass WDT die einzige interne Interrupt-Quelle ist, die in allen Schlafmodi verfügbar ist. Das macht das Schreiben der Bibliothek einfacher, bedeutet aber nicht, dass das Endergebnis das Beste ist, was sein könnte.

Der Schlafmodus mit dem niedrigsten Stromverbrauch ist Power-down. Watchdog, externer Interrupt und TWI-Match sind die einzig möglichen verfügbaren Interrupt-Quellen. Dies zwingt Sie dazu, einen externen Interrupt für Verzögerungen von mehr als 8 Sekunden zu verwenden. Der gesamte Stromverbrauch ist Power-down + externer Takt oder 0,5 uA + 0,13 uA = 0,63 uA

Werfen wir einen Blick auf den Energiesparmodus. Der einzige Unterschied zum Power-down besteht darin, dass die asynchrone Uhr aktiv ist, sodass Sie 32,768-kHz-Uhrquarz als Taktquelle verwenden können. Und es kann für Wake-up-Interrupts verwendet werden. Der Gesamtstromverbrauch ist Power-save, also Power-down + interne Uhr. Laut Datenblatt ist in diesem Modus ein Strom von etwa 0,95 uA erreichbar (obwohl Sie dafür einige fortgeschrittene Software-Tricks anwenden müssen, wie das Deaktivieren von Brown-Out, das Herunterfahren von ADC usw.).

Der Unterschied zwischen diesen Modi ist zweimal kleiner als selbst LDOs mit extrem niedrigem Ruhestrom verbrauchen (etwa 0,5 uA). In Anbetracht dessen, dass Sie damit all diese externen Teile loswerden können, würde ich sagen, dass dies eine durchaus praktikable Option ist.

Es sind zwei Nachteile zu berücksichtigen. Erstens, da die gleichen Pins für den Uhrenquarz wie für den normalen Quarzoszillator verwendet werden, sind Sie auf den internen RC-Oszillator als Systemtaktquelle beschränkt. Beachten Sie, dass der interne RC vom Benutzer auf eine Genauigkeit von etwa 1 % kalibriert werden kann, was für die meisten Anwendungen ausreichen sollte.

Zweitens gibt es kein Knopfzellen-Backup, das Sie zuvor erwähnt haben. Da dies jedoch eine batteriebetriebene Anwendung ist (ich nehme an, sonst würden Sie das Netzteil über die Uhr steuern, nicht über den MCU-Schlafmodus), sehe ich keine Notwendigkeit für ein Backup. Eine Batterie ist eine Batterie. Sie können einfache Mosfet-Schalter hinzufügen, um die Stromversorgung vom Rest der Schaltung abzuschalten und die Batterie mit dem ADC-Pin zu verbinden. Dann würden Sie beim Aufwachen die Batteriespannung messen und alles außer RTC deaktivieren, wenn es zu niedrig wird.