Wenn ich das selbe beim AVR64DD32 versuche, funktioniert die RTC nicht mehr, sobald ich den Overflow-Interrupt beim TCA0 aktiviere. Beide haben einen externen 3.6864MHZ-Quarz.
Ich finde im Datenblatt hier keinen Hinweis, auf abweichendes Verhalten zwischen den beiden Controller.
Kann das jemand hier auflösen? Kann ich die beiden Timer hier nicht unabhängig voneinander verwenden und müsste auf einen gemeinsamen ISR gehen (was ich ungern würde, da das zwei völlig getrennte Funktionen sind)?
Danke und Gruß
Micha
Hier der relevante code für die beiden:
1
//RTC
2
RTC.CTRLA=RTC_RTCEN_bm;// RTC aktivieren
3
while(RTC.STATUS>0);// Warten, bis der RTC bereit ist
Woher willst Du wissen, was relevant ist?
Du suchst doch erst den Fehler. Also poste das compilierfähige und getestete Programm als Anhang (*.c, *.zip).
C&P von Schnipseln in das Posting sollte man meiden, da hierbei oft Fehler passieren.
Da beide Typen im selben Errata-Blatt geführt werden, ist ein solcher Unterschied sehr unwahrscheinlich, die Kerne sollten gleich sein.
Was passiert, wenn der "irrelevante" Teil des Programms entfernt wird? Mit anderen Worten, wie immer: das Programm auf das absolute Minimum reduzieren, in den beiden ISR jeweils eine LED blinken lassen; dafür TCA-PER erhöhen. (apropos: da fehlt '-1').
Die Hex-Dateien müssen gleich sein, also vielleicht auch mal die des AVR64DD32 direkt auf den 28 übertragen (und umgekehrt).
bevor ich einen neuen Thread aufmache, teste ich das natürlich selbst erstmal entsprechend detailiert aus. Daher konnte ich das Problem auf die obigen Zeilen reduzieren. Den ganzen Rest hatte ich auskommentiert und auch entsprechend ein LED-Blinken eingefügt.
Zwecks Lesbarkeit (das ist sonst ein ZIP mit haufenweise irrelevantem =totem Code) habe ich dann die noch vorhandenen Restcode entsprechend hier reinkopiert. D.h. das oben ist bereits das Minimalprogramm, lediglich reduziert noch um das LED-Blinken (weil ich kein Problem mit Blinken habe, sondern dass der ISR schlicht nicht mehr ausgeführt wird):
sobald die Zeile mit FIXME einkommentiert wird, hört das Blinken auf
Funktionseinheiten wie RTC oder TCA usw. sollte man allein schon von der Logik her erst aktivieren, wenn die gesamte Konfiguration durchgelaufen ist. Kann ansonsten für unangenehme Überraschungen sorgen.
Die RTC Status Überprüfung ist an der Stelle sinnfrei. Das wird nach der Konfiguration geprüft, vorm aktivieren der RTC. Zudem dort noch zwischendrin der CPU Takt konfiguriert wird.
Erst CPU Takt konfigurieren, diesen mittels Status Register prüfen ob das Ding läuft, dann den Rest konfigurieren.
Kann mir schon vorstellen das dieses Durcheinander für Probleme sorgen könnte.
Minimalprogramm muss ein für uns kompilierbares Programm sein was den Fehler noch zeigt. Ansonsten läuft das immer auf das gleiche Problem hinaus. Der TO denkt der Fehler liegt hier, der liegt aber tatsächlich woanders. Fehlender Code wird gedanklich ausgeblendet usw. Irgendwo ist immer noch was, kannste glauben. Genau da wo man als TO nicht denkt.
das habe ich auch nicht verstanden, wenn der AVR eigentlich mit 3,6864MHz laufen soll. Irgendwo ist der Wurm drin, was wir nicht sehen. Nur ohne Minimalprogramm steck ich da nicht meinen Kopf weiter rein.
die CPU läuft mit dem externen Quarz, für die RTC nutze ich den internen Oszillator, weil ich damit eine einfache Sekunde hinbekomme.
Den starte ich natürlich vorher:
1
//Systemspeed 3,6864 MHz using external crystal
2
ccp_write_io((uint8_t*)&CLKCTRL.XOSCHFCTRLA,
3
CLKCTRL_RUNSTDBY_bm
4
|CLKCTRL_CSUTHF_4K_gc
5
|CLKCTRL_FRQRANGE_8M_gc
6
//| CLKCTRL_SELHF_XTAL_gc osci not crystal
7
|CLKCTRL_ENABLE_bm);
8
9
while(!(CLKCTRL.MCLKSTATUS&CLKCTRL_EXTS_bm)){;}
10
11
/* Clear Main Clock Prescaler */
12
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB,0);
13
14
//activate external clock
15
ccp_write_io((uint8_t*)&CLKCTRL.MCLKCTRLA,
16
CLKCTRL_CLKSEL_EXTCLK_gc
17
//| CLKCTRL_CLKOUT_bm //output clock on PA7
18
);
19
while(CLKCTRL.MCLKSTATUS&CLKCTRL_SOSC_bm){;}
Das Hex kann ich leider nicht einfach auf den 28er packen, da der seine LEDs an anderen Ports hat (Das ist kein Steckbrett sondern fertige PCBs).
Wenn ich das nochmal zusammenschreiben muss, muss ich das erst wieder zusammenbauen. Das ist ein größerer Act, weil ich da einiges aus dem Projekt rausnehmen muss, umkommentieren etc. Da komm ich frühestens am Wochenende dazu.
Vermutlich ist es weniger Aufwand, die RTC auf 50ms zu packen und dann halt bis 20 zu zählen für die Sekunden - dann brauche ich den TCA0 nicht mehr.
Verstehe ich nicht - Sie brauchen doch bloß das zusammenzufügen, was Sie uns (mittlerweile) fast vollständig gezeigt haben, und die LED-Pins ergänzen.
Also mehr oder weniger das, was Sie von uns erwarten, und was ich inzwischen selbst hingebogen habe (auch wenn's wie Kraut und Rüben aussieht und nur auf einem AVR32DD28 läuft, mangels AVR64DD32, leider).
Aber vielleicht liest ja ein Bereitwilliger mit einem 32er mit und nimmt sich die zehn Minuten Zeit, um es auszuprobieren.
PS:
Programm angehängt, vielleicht hilft es Ihnen.
Man sieht auch sehr schön das Auseinanderlaufen der LEDs, der OSC32K ist nun mal nicht sehr genau.
Aber vielleicht liest ja ein Bereitwilliger mit einem 32er mit und nimmt
sich die zehn Minuten Zeit, um es auszuprobieren.
Gelesen, getan: Bei mir funktioniert das Programm aus dem Anhang des vorhergehenden Beitrags von S. L. (sldt), 13.02.2025 19:49, (leicht angepasst, siehe unten) wie zu erwarten auf einem meiner AVR64DD32; die an PA7 und PA6 angeschlossenen LEDs blinken etwa im Sekundentakt, wobei die Abweichung der beiden Oszillatoren anhand der "Schwebung" sichtbar wird.
Allerdings habe ich gerade keinen 3,6864-MHz-CXO zur Hand, sodass ich ersatzweise die Default-Einstellung von 4 MHz internem Oszillator belassen habe. Zudem habe ich das Programm in Assembler umgeschrieben (siehe Anhang), weil ich gerade keine Lust hatte, mir extra einen Compiler zu installieren. Sollte ja aber hier beides keinen wesentlichen Unterschied machen.
Der TCA ist ein vollwertiger Universalcounter mit drei Compare Channels.
Der RTC ist ein Ultra Low Power Langzeitcounter - "Sleep Counter".
Für einfachere Aufgaben wie z.B. Periodic Interrupt kann man die TCBs benutzen.
https://www.mikrocontroller.net/attachment/615726/AVR_TCB.png
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
ISR(TCB1_INT_vect)
5
{
6
PORTD.OUTTGL=PIN4_bm;// toggle PD4 (50ms)
7
TCB1.INTFLAGS=TCB_CAPT_bm;// clear TCB1 interrupt flag
8
}
9
10
ISR(TCB2_INT_vect)
11
{
12
PORTD.OUTTGL=PIN5_bm;// toggle PD5 (1s)
13
TCB2.INTFLAGS=TCB_CAPT_bm;// clear TCB2 interrupt flag