Hi,
ich nutze erfoglreich bei einem AVR64DD28 den RTC und TCA im
Interruptmodus (RTC für Interrupt alle 1 Sekunde, und den TCA alle 50ms)
- siehe auch Beitrag "AVR64DD: TCA0.SINGLE.PER verändert util/delay-Verhalten"
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
Michael W. schrieb:> Hier der relevante code für die beiden:
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.
> Kann das jemand hier auflösen?
Kann ich nicht, aber ein paar Gedanken beitragen:
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).
Hi,
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
Grüße Micha
"Then carry it along"
Nur soviel:
> das oben ist bereits das Minimalprogramm
Es handelt sich um ein Programmfragment - wo z.B. wird der Oszillator
für den 3.6864 MHz-Quarz eingeschaltet?
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.
Dem letzten Absatz kann ich voll&ganz zustimmen.
Und: diese eine Zeile (4) mit dem XOSC32K habe ich ohnehin nicht
verstanden - der RTC läuft anschließend doch mit OSC32K.
Hallo,
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.
Beim ersten Überfliegen dachte ich, dass Michael W. mit zwei Quarzen
arbeitet: 3.6864 MHz als Hauptoszillator, 32 KiHz für den RTC-PIT.
> Nur ohne Minimalprogramm steck ich da nicht meinen Kopf weiter rein.
Das sagte ich mir dann auch - aber ein interessanter Fall ist es schon.
finde ich.
Hi,
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.
Grüße und Danke
Micha
> ... Das ist ein größerer Act ... Wochenende
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.
S. L. schrieb:> 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