PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit Timer0 (Overflow Interrupt) [gelöst]



Maximus
03.09.2006, 12:45
Hallo,

Nachdem ich es in den letzten Tagen mit weniger Fehlversuchen als vermutet geschafft habe eine LED mit meinem atmega8 zum leuchten zu bringen, habe ich nun ein Problem mit dem Timer0.

Ich möchte die LED an Port C 0 nach ungefähr 1s zum leuchten bringen.
Da ich an dem atmega8 noch nichts bezüglich der Taktfrequenz geändert habe, läuft dieser auf 1MHz. Ist es dann richtig dass der Timer (Vorteiler: 1024) alle 1000000 / 1204 / 256 = ca. 3,8 pro Sekunde das Overflow Interrupt auslöst? (Im TIMSK Register ist TOIE0 gesetzt und Interrupts sind aktiviert sei () )

Der komplette Quelltext sieht so aus:

#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>

#define OfPS 4

volatile uint8_t ofCount;

SIGNAL(SIG_OVERFLOW0)
{
ofCount++;
}

int main (void)
{
DDRC = 0x05;
PORTC = 0x00;

TCCR0 |= (1 << CS02) | (1 << CS00);
TIMSK |= (1 << TOIE0);

ofCount = 0;
sei ();

while (1)
{
if (ofCount >= OfPS)
{
PORTC |= (1 << PC0);
ofCount = 0;
}
}
}

Der Compiler meckert nicht, die LED fängt aber auch nicht nach ca. 1s an zu leuchten (oder besser gesagt sie fängt gar nie an zu leuchten).
Ich hab den Quelltext auch schon entsprechend abgeändert (PC0 wird im SIG_OVERFLOW0 auf High geschalten -> ist leider auch nichts passiert). Wieso löst er den Interrupt nicht aus?

Ich bin am verzweifeln :( .

MFG
Maximus

PicNick
03.09.2006, 13:00
Vielleicht bin ich blind, ich seh nix Böses im Code:
ABER
Die setzt zwar portc.0
aber nie wieder zurück ???

Anderes: ist der Watchdog disabled ? (-->fuses)

SprinterSB
03.09.2006, 13:08
Willst du an PortC5 arbeiten oder an PortC0?

uwegw
03.09.2006, 13:09
Die Initialisierung des Timers passt so, ich machs in einem Programm von mir genauso. Bei 8MHz Takt wird da alle 33ms ein Interrupt ausgelöst, kommt also hin mit deinen ca. vier Interrupts pro Sekunde (264ms).
Die Schreibweise mit SIGNAL ist allerdings veraltet, bei der neuen AVR-GCC-Version sollte man ISR(TIMER0_OVF_vect) verwenden.
Ist die Hardware überhaupt in Ordnung? Kannst du die LED ohne den Timer direkt zum Leuchten bringen?

Maximus
03.09.2006, 14:25
@PicNick
Das Port.C nicht zurückgesetzt wird ist gewollt. Ich möcht es jetzt einfach mal hinbekommen, dass die LED überhaupt Timer gesteuert angeht.

Das mit dem Watchdog werd ich überprüfen! (aber wieso sollte es an dem watchdog liegen, der könnte doch höchsten ein dauerreset des Mikroprozessors bewirken, oder? -> Dauerreset passiert nicht da eine LED an PortC2 die ganze Zeit leuchtet)
Edit:\\ Ponyprog meint das der Watchdog Timer nicht an ist (WDTON = kein Häckchen)

@SprinterSB:
Ich arbeite hauptsächlich an PortC0 (soll Timer gestuert auf High schalten)
Jedoch hab ich auch noch eine Status LED an PortC2 die leuchtet wenn der Port auf LOW steht (also bei diesem Programm die ganze Zeit -> funktioniert auch)

Ich kann jetzt nur eine Vermutung anstellen wie du auf den PortC5 kommst (wegen dem DDRC=0x05? -> 0b00000101 -> PortC2 und C0 auf Ausgang)

@uwegw
Ja Die LEDs kann ich ohne Timer ohne Probleme zum leuchten bringen, somit denke ich das die Hardware in Ordnung ist.
Da ich auch schon gelesen hatte das SIGNAL veraltet ist und man nun ISR benutzen sollte, hatte ich es zu beginn so, als es nicht funktioniert hat, habe ich auf SIGNAL() umgestellt.

Jedoch (TIMER0_OVF_vect)? - Ist das auch als _VECTOR(9) definiert? (Wen ja wo?)

MFG
Maximus

uwegw
03.09.2006, 14:40
Jedoch (TIMER0_OVF_vect)? - Ist das auch als _VECTOR(9) definiert? (Wen ja wo?)

In der iom8.h (wird über das #include <avr/io.h> eingebunden) steht:
/* Timer/Counter0 Overflow */
#define TIMER0_OVF_vect _VECTOR(9)
#define SIG_OVERFLOW0 _VECTOR(9)

Man kann also noch beide Schreibweisen verwenden, der Compiler spuckt nur ne Warnung raus, dass die signal.h veraltet ist. Funktionieren sollte es aber trotzdem.

Hast du eigentlich im Makefile angegeben, dass du einen Mega8 benutzt? Sonst wird nämlich evtl. nicht die iom8.h eingebunden, sondern ne Datei für nen anderen AVR mit anderen Interruptvektoren...

Maximus
03.09.2006, 14:50
Uf. Hab ich eine so veraltete Version von WinAVR installiert? Den in meiner iom8.h gibt es kein TIMER0_OVF_vect nur SIG_OVERFLOW0.

Ich hab die WinAVR Version 20040720 von der aktuellen robotikhardware CD.

Dem Compiler übergebe ich auch den Typ des Mikroprozessor als Parameter (-mmcu=atmega8).

MFG
Maximus

SprinterSB
03.09.2006, 19:19
Also ich seh da auch nix. Mit der Version von avr-gcc kannst du gut leben. Bist du sicher, daß die LED richtig verdrahtet ist?

Versuch mal sowas, vielleicht geht's am Anfang einfach nur zu fix?



int main (void)
{
DDRC = (1 << PC0) | (1 << PC2);
PORTC = 0x00;

TCCR0 = (1 << CS02) | (1 << CS00);
TIMSK |= (1 << TOIE0);

ofCount = 0;
sei ();

while (1)
{
if (ofCount >= OfPS)
{
PORTC ^= (1 << PC0);
ofCount = 0;
}
}
}

Maximus
03.09.2006, 20:52
@SprinterSB Ich werd das mal ausprobieren!
Jedoch kann da nichts zu fix gehen, da in dem Quelltext die LED bei ofCount >=4 einfach angeschalten wird und auch angeschalten bleibt. Jedoch bleibt gerade dieses anschalten aus.

Die LED ist richtig verdrahtet, wenn ich sie ohne Timer aufrufe leuchten sie wie gewünscht.

Ich hab jetzt auch mal den Mikroprozessor mit meinem zweiten atmega8 ausgetauscht und auch mal versucht den 2. 8-Bit-Timer zu benutzen, beides mal hat sich jedoch nichts getan.

Für jede weitere Idee bin ich dankbar und auch ein großes Danke an alle die mir bisher versucht haben zu helfen!

MFG
Maximus

SprinterSB
04.09.2006, 08:41
Wenn die LED an PortC2 leutet, ist sie also nach VCC verdrahtet. ABer mir fällt nix mehr dazu ein. Evtl sind die Fuses verstellt und der µC läuft nicht los, dann dürfte LED2 aber nicht brennen. Oder du hastn Fehler im Makefile (falls du make benutzt) und es wird kein neues HEX egeriert oder was anderes gebrannt als du denkst?

Oder du hast vergessen, die signal.h zu includen, die braucht man bis v3.4.4 oder so. Die gcc-Version siehst du mit
avr-gcc -v

Mach mal folgendes:

> avr-gcc -mmcu=atmega8 -Os timer0.c -o timer0.elf
> avr-objdump -d timer0.elf
und poste die Ausgabe. Wenn ein <SIGNAL> zu Beginn des ISR-COdes steht, dann wurde die ISR nicht eingetragen und du loops immer wieder via __bad_interrupt in den RESET rein. Falls <__vector_9> da steht, liegt der Fehler woanders

Code fehlerhaft:

0000005c <SIGNAL>:
5c: 80 91 60 00 lds r24, 0x0060
60: 8f 5f subi r24, 0xFF ; 255
62: 80 93 60 00 sts 0x0060, r24
66: 08 95 ret


Code korrekt:

0000005c <__vector_9>:
5c: 1f 92 push r1
5e: 0f 92 push r0
60: 0f b6 in r0, 0x3f ; 63
62: 0f 92 push r0
64: 11 24 eor r1, r1
66: 8f 93 push r24
68: 80 91 60 00 lds r24, 0x0060
6c: 8f 5f subi r24, 0xFF ; 255
6e: 80 93 60 00 sts 0x0060, r24
72: 8f 91 pop r24
74: 0f 90 pop r0
76: 0f be out 0x3f, r0 ; 63
78: 0f 90 pop r0
7a: 1f 90 pop r1
7c: 18 95 reti

Maximus
04.09.2006, 09:05
Ja die LED an PortC2 ist nach VCC verdrahtet, die an PortC0 nach GND.

Makefile? - Gehört hab ich schonmal davon, aber was es ist weiß ich nicht.

Ich erstelle die hex Dateien eigentlich immer über die Konsole (bzw. seit neustem mit selbst geschriebenen Tool, damit ich das nicht jedes mal die ganzen Pfade/Parameter tippen muss) nach dem Tutorial "Hallo Welt für AVR" (K: Quellcode C).
Wie find ich den raus ob in der HEX das drin steht was ich will?

Irgendwie glaub ich, dass doch ein Hardwareproblem vorliegt.

Ich werde jetzt erstmal versuchen mit Bascom den Timer aufzusetzen (wird wahrscheinlich auch nicht funktioniert) um einen Softwarefehler ausschließen zu können. //Edit: tja hat wunderbar funktioniert mit dem Timer

//Edit2: Tatsächlich lag es an der uneingebundenen signal.h (version 3.4.1 - und sowas ist auf der robotikhardware cd vom 31.August.2006 -.-") - Ein RIESENGROßEN DANK an alle die mir geholfen haben, vor allem an SprinterSB.

MFG
Maximus

SprinterSB
04.09.2006, 09:12
Du brauchst nur die beiden obigen Zeilen einzugeben. Ich denke, es wird falscher Code generiert (wird zumindest bei mir mit avr-gcc 3.4.4 wenn ich die signal.h weglasse).