TCD5.INTCTRLA|=TC45_OVFINTLVL_HI_gc;// Interrupt hat höchste Priorität
37
TCD5.PER=0x07A1;// entspricht 1.953, sollte eine Sekunde ergeben
38
//TCD5.CNT = 65000L;
39
40
sei();
41
42
/* Replace with your application code */
43
while(1)
44
{
45
PORTD.OUTTGL=PIN5_bm;
46
for(uint8_ti=0;i<100;i++)
47
{
48
_delay_ms(5);
49
}
50
51
}
52
53
}
Was sollte passieren? Nun: es sollten Pin D5 (in der Hauptschleife
getoggelt) mit 2 Hz und Pin D6 (über den Timer getoggelt) mit 1 Hz
blinken! Was tun sie: Nach Reset gehen Sie sofort an und blinken dann
unregelmäßig (!!!!!!!!!!!!!!!!!) mit einer Periode zwischen 1 und 10
sec. (Oder so!)
Nein, das Programm hat keinen Sinn! Es ist nur zum Verständnis
geschrieben.
Ja, wenn ich den ganzen Timerzirkus rausnehme, dann blinkt PIN D5 wie
erwartet. Ich habe den Eindruck, dass der Timerkrempel den ganzen µC
blockiert!
@ ArduStemmi (Gast)
>ISR( TCD5_OVF_vect )>{> PORTD.OUTTGL = PIN6_bm;>}
Beim Überlauf von TCD5 soll IO in PD6 umgeschaltet werden.
>> //Oszillator auf 2Mhz stellen> OSC.CTRL |= OSC_RC2MEN_bm;> // Warten bis der Oszillator bereit ist> while(!(OSC.STATUS & OSC_RC2MRDY_bm));> //Schützt I/O Register, Interrupts werden ignoriert> CCP = CCP_IOREG_gc;> //aktiviert den internen Oszillator> CLK.CTRL = (CLK.CTRL & ~CLK_SCLKSEL_gm) | CLK_SCLKSEL_RC2M_gc;
Das ist Unsinn, denn der 2 MHz Oszillator ist nach dem Reset
standardmäßuig aktiv. Kann man alles weglassen.
> TCD5.CTRLA |= TC45_CLKSEL_DIV1024_gc; // Timer 4 Vorteiler 1024
Sowas ist hier ungünstig bis falsch. Eine direkte Zuweisung ist das
Mittel der Wahl.
TCD5.CTRLA = TC45_CLKSEL_DIV1024_gc; // Timer 4 Vorteiler 1024
> TCD5.CTRLB |= TC45_WGMODE_NORMAL_gc; // NormalMode> TCD5.INTCTRLA |= TC45_OVFINTLVL_HI_gc; // Interrupt hat höchste Priorität
Hier ebenfalls.
> TCD5.PER = 0x07A1; // entspricht 1.953, sollte eine Sekunde
ergeben
Warum schreibst du das in Hex, das kann kein Mensch verstehen.
2 MHz / 1024 = 1953 Hz.
Also eher
TCD5.PER = 1953;
sei();
> /* Replace with your application code */> while (1)> {> PORTD.OUTTGL = PIN5_bm;> for (uint8_t i = 0; i < 100; i++)> {> _delay_ms(5);> }> }
Hier läßt du PD5 per Software blinken.
>>Was sollte passieren? Nun: es sollten Pin D5 (in der Hauptschleife>getoggelt) mit 2 Hz und Pin D6 (über den Timer getoggelt) mit 1 Hz>blinken! Was tun sie: Nach Reset gehen Sie sofort an und blinken dann>unregelmäßig (!!!!!!!!!!!!!!!!!) mit einer Periode zwischen 1 und 10>sec. (Oder so!)
Klingt nach einem Watchdogreset. Ist der per Fuses ausgeschaltet?
>Ja, wenn ich den ganzen Timerzirkus rausnehme, dann blinkt PIN D5 wie>erwartet. Ich habe den Eindruck, dass der Timerkrempel den ganzen µC>blockiert!
Dann läuft was schief ;-)
Mach mal wie oben geschrieben normale Zuweisungen beim Timer-Init.
Danke für Deine Erläuterungen! Ich verstehe nicht, warum die direkte
Zuweisung anders funktionieren sollte! Kannst Du das bitte kurz
erläutern?
Die Einstellung des Taktes ist nur zur Sicherheit drin! Ich wollte halt
sicher gehen, dass es nicht am falschen Takt liegt!
Wie sollten denn die Fuses stehen, um den Watchdog zu unterdrücken? Und,
warum kann man beim XMega alles per SW einstellen, nur den WD
ausgerechnet nicht?
@ ArduStemmi (Gast)
>Danke für Deine Erläuterungen! Ich verstehe nicht, warum die direkte>Zuweisung anders funktionieren sollte! Kannst Du das bitte kurz>erläutern?
Das kommt auf den vorherigen Zustand des Registers an. Manchmal will man
das, manchmal eben nicht.
>Wie sollten denn die Fuses stehen, um den Watchdog zu unterdrücken? Und,>warum kann man beim XMega alles per SW einstellen, nur den WD>ausgerechnet nicht?
Frag das Atmel.
Prbier einfach mal die aufgeräumte Version.
1
#define F_CPU 2000000L
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
6
volatileuint8_ttmp=0;
7
8
ISR(TCD5_OVF_vect)
9
{
10
11
PORTD.OUTTGL=PIN6_bm;
12
}
13
14
15
intmain(void)
16
{
17
18
PORTD.DIR|=PIN5_bm|PIN6_bm|PIN7_bm;// PORTD Pins 5, 6 und 7 sind Ausgang
also ich hab das gerade mal nachgestellt. Auch mit einem ATxmega32e5.
Bei mir blinkt PD5 regelmäßig ... allerdings komischerweise zu langsam
(statt 2 Hz eher mit 0,3 Hz). Dafür leuchtet PD6 durchgehend. Zumindest
sieht es so aus. Tatsächlich wird jedoch die ISR ständig aufgerufen.
Laut Oszi toggelt PD6 alle 14,5 us.
Josef H. schrieb:> Hei,> mit TCD5.INTFLAGS |= 1;> in interrupt Flag löschen.
Winn ich im ISR für den Overflow Interrupt den Interrupt Flag jedesmal
lösche, dann klappt es. Soll das so sein? Das macht man aber beim Atmega
nicht so! Also ich jedenfalls. Und es steht meines Erachtens auch
nirgends.
PS: aufgeräumte Version + Interrupt-Flag löschen funktioniert zumindest
bei mir ;-)
Lustigerweise blinkt auch PD5 jetzt im erwarteten Takt und nicht wie
zuvor zu langsam ;-)
Kotzmodus an: Das ist, was ich an diesem Hobby so hasse: völlig
unerwartetes Verhalten, durch triviale Änderung beherrschbar, aber nicht
erklärbar!
Kotzmodus aus!
Hallo,
ISR( TCD5_OVF_vect )
{
TCD5.INTFLAGS = TC5_OVFIF_bm;
PORTD.OUTTGL = PIN6_bm;
}
dann funktioniert es!!
Beim XMega32e5 wird vermutlich das Interrupt-Flag beim ISR-Aufruf nicht
automatisch gelöscht!
Gruß G.G.
Gerhard G. schrieb
> Beim XMega32e5 wird vermutlich das Interrupt-Flag beim ISR-Aufruf nicht> automatisch gelöscht!
Nicht nur vermutlich.
Einfach mal vorher das Datenblatt lesen.
Ist eine Besonderheit bei den E5...
Zeig' mir mal, wo es im Datenblatt steht! Viele andere und auch ich,
haben des so explizit nicht herauslesen können! Bitte sag mir jetzt
nicht: Nirgends steht, dass es gelöscht wird, daraus folgt ...! Das ist
schon klar! Aber, da es sich um eine Besonderheit handelt, hätte man
explizit drauf aufmerksam machen müssen.
Für mich ist das Thema damit erledigt. Geärgert habe ich mich auch
genug. Ich spiele weiter mit dem Mega rum!
ArduStemmi schrieb:> Und, warum kann man beim XMega alles per SW einstellen, nur den WD> ausgerechnet nicht?
Weil ein Wachhund, der sich von einer irrlaufenden Firmware
abschlachten lässt, kein sinnvoller Wachhund ist.
Man kann ihn natürlich auch per Software schalten, aber wenn
man ihn per Fuse aktiviert, dann ist das eine Nummer sicherer, und
er darf sich nicht wieder lahmlegen lassen.
(Hat mit deinem Problem nun nichts mehr zu tun, aber die Frage war
noch nicht beantwortet worden.)
Hameg schrieb:> 13.13.11, S191:>> OVFIF will not be cleared when the interrupt vector is executed. The> flag is cleared by writing a one to its bit location.
Ok, Du hattest Recht! Ich habe das nicht gesehen!
ArduStemm schrieb:>> OVFIF will not be cleared when the interrupt vector is executed. The>> flag is cleared by writing a one to its bit location.
Das trifft bei dem E5 übrigens auf fast alle IRQ Flags zu. Über die
Nummer bin ich auch schon gestolpert. Ist man nicht gewöhnt und
überliest es gleich mal im Datenblatt. Beim OVFIF steht es wenigstens
noch drin, das es nicht gelöscht wird ;-) Wenn da einfach nur "nichts"
steht, fängst Du richtig an zu suchen, weil beim AVR rechnet man nicht
damit...
Willi schrieb:> Das trifft bei dem E5 übrigens auf fast alle IRQ Flags zu.
Das stimmt nicht. Es trifft lediglich auf die Flags zu, die einen
DMA-Tansfer auslösen und von dem DMA-Transfer auch zurückgesetzt werden
und bei denen dieses Verhalten sinnvoll ist, da ein automatisches
Löschen in Verbindung mit DMA eher Fehler provozieren würde. Flags, die
ohnehin durch die Hardware (DRE, RXD...) oder durch Interrupte gelöscht
werden, sind davon nicht betroffen. Es schadet daher nicht, beim
Programmieren jedes verwendete Flag im DB auf sein Verhalten hin zu
überprüfen. Einige dieser "besonderen" Flags sind auch in den anderen
XMEGAs der Serien A-D zu finden.