mega16 counter0 & IRQ

Gast #303547
Lesenswert?

Hallo,

ich bin gerade dabei, eine Pulsbreiten / Pulsmodulation aufzubauen.
Aber irgendwie bekomme ich den IRQ nicht zum Ticken.
Vielleicht erbarmt sich ja mal einer und sieht durch was ich falsch
gemacht habe.

Die Funktion "pbInit(BYTE time)" soll den Timer0 mit IRQ aktivieren.


Die Funktion "SIGNAL(SIG_OVERFLOW0)" soll bei Interrupt aufgerufen
werden und eine Leistungssteuerung an Port C aufrufen.

Ich versuche im Moment erst mal den Interrupt bei Überlauf des Counters
1 aufzurufen, später soll auf Vergleichswert Time umgeschrieben werden.
Ich bin für jede Hilfe dankbar.


Grüße

Tom
Angehängte Dateien:
Gast #303549
Lesenswert?

Ich glaube du setzt die Timer Interrupt Mask (TIMSK) falsch. Bit 0 (das
erste Bit - welches du auf 1 setzt) ist TOIE0 (Timer Overflow Interrupt
Enable). Du benötigts OCIE0.

Ich schreib es in der Form, dann muss man nicht selbst die Bits
zusammensuchen.
TIMSK |= _BV(OCIE0);

oder auch:
 TCCR2 = (_BV(WGM21) | _BV(CS22) | _BV(CS21))
Zum gezielten zurücksetzen eines Bits:
 TIFR &= ~_BV(OCF2)

Vorteil: man sieht auf den ersten Blick, welche Bits gemeint sind.

Das Makro _BV(X) entspricht (1 << X). Bit 0 wird also X mal nach links
geschoben. Die Werte für X sind im iom16.h deklariert.
_BV(X) kann vom Compiler schon zur Compilezeit aufgelöst werden.
Gast #303550
Lesenswert?

Hallo,

erst mal danke das ihr euch durch meinen Code gewühlt habt.

@ Anton:
Ja ich weis ich sollte mit die Flagnahmen und den  (1 << X )
Programmierstiel angewöhnen. Aber irgendwie widerstrebt es mir einfach
den Proz sinnlose schifft Operationen ausführen zu lassen.

Das Register TIMSK. ist richtig gesetzt  auch laut Datenblatt  BIT 1 =
Compare  BIT 0 = Overflow.
Leider ist der mein Kommentar  im Source nicht so ganz stimmig  sonst
währe es einfacher gewesen den Code zu lesen

@ Alle
Mittlerweile habe ich das ganze irgendwie zum Ticken bekommen. Das
heißt der Source ist scheinbar doch IO. warscheinlich war das eine
Kombination von mehreren Porblemen, so dass ich nicht draufgekommen
bin. 1. falscher Interruptvector  2. bei erreichen des zählwertes
Rüpcksetzen des Timers (TCCR0 COM01 COM00 Clear on compare Match) ...
na ja und wenn man seinen ersten IRQ auf einem Atmel programmiert dann
ist man noch zusätzlich verunsichert.

Nochmals vielen Dank an alle

ich hätte noch eine Frage.  Gibt es einen Interruptvector der bei
vergleich mit dem OCR0 register   . TIMSK   BIT 1 =  Compare
angesprungen werden kann? wenn ich  SIGNAL(SIG_OVERFLOW0) als IRQ
Routine angebe gibt das einen reset (klar defaultvector... )

Zweitens wie kann man mehrere irq Routinen in ein c-file schreiben ?
wenn ich 2 mal SIGNAL(..) schreibe mault mein Compiler

Grüße

Tom
Gast #303551
Lesenswert?

"@ Anton:
Ja ich weis ich sollte mit die Flagnahmen und den  (1 << X )
Programmierstiel angewöhnen. Aber irgendwie widerstrebt es mir einfach
den Proz sinnlose schifft Operationen ausführen zu lassen."

Das ist ein Irrtum. Das wird vom Compiler beim Compilieren gemacht,
nicht zur Laufzeit vom Prozessor. Kostet dich keinen einzigen Takt
(wenn man davon absieht, dass das Compilieren Bruchteile von ms länger
dauert :-)
Gast #303552
Lesenswert?

Tom,
der ATmega muss keine sinnlosen shift Operationen bei (1<<X) machen,
wenn X eine feste Zahl ist. Das macht dein PC schon während des
compilierens. Danach steht im Assemblercode auch nur die daraus
resultierende Hex-Zahl drin.

SIGNAL(SIG_OUTPUT_COMPARE0) ist der Interrupthandler, der angesprungen
wird, wenn der Timer bis zum Wert von OCR0 gezählt hat. Sofern man das
Output Compare Zeugs eingestellt hat.

Ich habe das mit SIGNAL(SIG_INTERRUPT2) im gleichen File kombiniert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren