Hmm, ein bißchen wirr sieht mir der Code aus.
Ich gehe mal der Reihe nach durch:
> #include <stdio.h>
Wird gar nicht benötigt.
> #include <io.h>
Bitte #include <avr/io.h> schreiben.
> sbi(PORTB,PINB2);
sbi() sollte in neuem Code nicht mehr benutzt werden. Ein Standard-C
Konstrukt ist:
PORTB |= (1 << PORTB2);
AVR-GCC bietet für die Bitschieberei noch _BV():
PORTB |= _BV(PORTB2);
PINB2 sollte dem PINB-Register vorbehalten bleiben (Bit-Eingabe),
entweder PORTB2 oder einfach nur 2 schreiben, sonst verwirrt das eher.
> if (counter == 0x00)
> {
> output_index = 0;
> }
Hmm, danach wird der `counter' trotzdem weiter fleißig runtergezählt,
sprich, er geht in den negativen Bereich. Ich vermute, daß das nicht
Deinen Intentionen entspricht und das hier der eigentliche Bug ist.
Wahrscheinlich müßtest Du den wieder bei 7 anfangen lassen.
> outb(TCCR2, 0x1D); // toggle oc2, ctc mode, prescaler auf
1/...,
Davon abgesehen, daß outb() auch nicht mehr benutzt werden sollte, das
Ganze wird mit
TCCR2 = _BV(COM20) | _BV(WGM21) | _BV(CS22) | _BV(CS20);
ein Stück verständlicher. Prescaler 1/1024.
> OCR2 = 150;
Besser den Präprozessor rechnen lassen. Mal in der Annahme von 1 MHz
Takt (interner RC-Oszillator):
#define FOSC 1000000L
#define PRESCALE2 1024
#define OCR2VAL 154 /* milliseconds */
OCR2 = OCR2VAL * (FOSC / PRESCALE2) / 1000;
> init_timer();
>
> while (counter != 0)
> {}
Hmm, init_timer() hat counter soeben auf 0 gesetzt, warum sollte die
Warteschleife also einen Wert != 0 vorfinden?
> Bits[0]=0x00;
...
> Bits[6]=0x00;
Davon abgesehen, daß ein Byte pro Bit ziemliche Platzverschwendung
ist, sollte diese Initialisierung nicht schon vor dem Start des Timers
erfolgen?
Eine Möglichkeit wäre eine echte Initialisierung bei der Definition
der
Variablen:
Bits[] = {0, 0xff, 0, 0xff, 0, 0xff, 0, 0xff, 0};
#define NBITS (sizeof(Bits) / sizeof(Bits[0]))
Dann benutzt Du statt der magischen 7 immer NBITS und hast auf diese
Weise eine Konstante, die sich automatisch selbst an die Größe des
Arrays Bits[] anpaßt.
> return(0);
Hier fällst Du aus main() heraus und hoffst, daß die eingebaute
Funktion exit() in der Tat eine Endlosschleife mit gestatteten
Interrupts ausführt. Das ist kein guter Stil, schreibe lieber die
Endlosschleife explizit selbst hin:
/* Die Interrupts machen den Rest. */
for (;;)
;