PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Es wird kein Interrupt ausgelöst



MrTaco
19.07.2010, 14:29
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>


SIGNAL (SIG_OUTPUT_COMPARE1B)
{
PORTB ^= 0xFF;

}


int main (void)
{
TIMSK |= 0b00001000;
TCCR1B|= 0b00001010;

DDRB = 0xFF;
OCR1B = 303;
sei();

while(1)
{

}
return 0;
}


was habe iich hier falsch gemacht?

Jaecko
19.07.2010, 14:41
Welcher Controller?
Dann kann man mal schauen, welche Bedeutung die Bits in TIMSK und TCCR1B haben.

Was soll das Ding nach deiner Erwartung tun?
Und was tut es stattdessen?

markusj
19.07.2010, 14:42
Ja!

mfG
Markus

PS: Keine Information über den verwendeten AVR, Magic Values zur Registerinitialisierung, alte Interruptschreibweise.

MrTaco
19.07.2010, 15:19
atmega16
er soll nach bestimmten Abständen den ganzen port B Toggeln

Jaecko
19.07.2010, 15:25
Und was tut er? Toggelt er nicht? Toggelt er zu schnell/zu langsam?
Wenn nichts passiert, welchen Zustand hat der Port (High/Low)?

askazo
19.07.2010, 15:27
Du lässt den Counter im CTC-Modus (Mode 4) laufen, der Counter zählt also von 0 - OCR1A. Da Du OCR1A nicht gesetzt hast, bleibt das Register im Reset-Zustand (also 0x0000) und Dein Counter zählt unsinnigerweise von 0 bis 0....

Lösung des Problems: Entweder einen Wert für OCR1A setzten, der > 303 ist, oder WGM12 in TCCR1B nicht setzten.

Gruß,
askazo

MrTaco
19.07.2010, 16:06
Der soll doch nen interrupt machen wenn Zähler = OCR1B ist.
Wenn ich das bis OCR1A mache wie du es gesagt hast dann Klappt es auf einmal aber warum?
Ich habe doch SIG_OUTPUT_COMPARE1B geschrieben und nicht
SIG_OUTPUT_COMPARE1A.

Und im im Timer Interrupt Mask register ist ein Interrupt für Compare A nicht aktiviert sonder nur für Compare B.

Jaecko
19.07.2010, 16:40
Datenblatt S. 98:
"In Clear Timer on Compare or CTC mode [...], the OCR1A or ICR1 Register
are used"

OCR1B als Vorgabewert geht im CTC-Modus nicht.

askazo
19.07.2010, 16:47
Der soll doch nen interrupt machen wenn Zähler = OCR1B ist.
Genau das macht er ja auch - nur dann muss der Zähler auch erst mal bis zu dem Wert kommen, der in OCR1B steht.

So wie Du den Timer eingestellt hast, wird das OCR1A-Register dafür verwendet, den Maximalwert des Zählers zu definieren. Wenn Du z.B. den Wert 350 ins OCR1A-Register schreibst, zählt der Zähler von 0 bis 350 und fängt dann wieder bei 0 an. Wenn er dann beim Zählen den Wert erreicht, der in OCR1B steht, wird auch der entsprechende Interrupt ausgelöst.

Im Standard-Modus zählt der Zähler immer von 0-65535 (0xFFFF). Dazu müsste aber das Bit WGM12 bei der Initialisierung auf 0 gesetzt werden (also TCCR1B|= 0b00000010; )

Schau Dir mal im aktuellen Datenblatt vom ATMega16A die Tabelle auf Seite 112 an, besonders die Spalte "TOP". Vielleicht wird's dann klarer ;)

Gruß,
askazo

MrTaco
19.07.2010, 16:48
ahhhh jetzt verstehe ich DANKE EUCH BEIDEN.
echt top von euch.