Schoenen guten Tag Ich bin noch ziemlich neu in der Mikrocontroller Programmierung, beschaeftige mich aber in letzter Zeit relativ intensiv damit. Ich habe nun versucht ein C-File zu schreiben mit dem ich ueber einen 8 Bit Timer und Output Compare Interrupt eine bestimmte Bitfolge zu generieren(nicht togglen) was leider nicht funktioniert. Beim compilieren bekomme ich auch keinerlei Fehlermeldungen oder Warnungen und ich habe schon ueber den OC2 getestet(ueber Oszi) ob der Timer funktioniert, und er funktioniert. Der Fehler muss also wo anders liegen aber ich komm beim besten Willen nicht drauf. Falls also jemand Lust und Zeit hat mal drueber zu schauen, waere ich sehr dankbar. Danke MfG Stefan PS: -ich benutze einen Atmega 128 -File im Anhang
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 (;;) ;
Danke Joerg Werd mich jetzt mal mit den ganzen Vorschlaegen auseinandersetzen. Vielen Dank schon mal. Mfg Stefan
Da ich an dem Code 'mitschuldig' bin, war ein schneller Hack zwischendurch und sollte nur einige Dinge aufzeigen, will ich mal auch etwas zur Aufloesung beitragen. Damit der Compiler ueberhaupt einen Interruptvektor erzeugt: #include <avr/signal.h> einfuegen. Zumindest sehe ich dann im AVR-Studio einen belegten Interruptvektor, ohne das Include sind alle ausser dem Resetvektor leer. Nochmal ein Dank an Joerg aus DD. Jens
@Jörg Wunsch: Wo steht denn, dass man sbi usw. nicht mehr verwenden sollte? Und wieso outb? dachte es heißt outp?
Das steht in der Doku! http://www.nongnu.org/avr-libc/user-manual/index.html genauer: http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html Gruß, Patrick...
Ich fürchte, es steht noch nirgends geschrieben. ;-) outb() und outp() sind mittlerweile identisch und beide gleichermaßen ,,nicht für Neuentwicklungen''. Die von Atmel bevorzugt propagierte Schreibweise ist die direkte Zuweisung, also REGISTER = Wert; avr-gcc/avr-libc konnten dies anfangs nicht, aus dieser Zeit stammen all die outb/outp/inb/inp Makros. Auch die sbi/cbi Makros stammen aus dieser Zeit. Letztere werden vor allem deshalb nicht mehr empfohlen, weil sie dem Benutzer suggerieren, daß sie automatisch die entsprechenden Assemblerbefehle generieren würden. Das tun sie aber gar nicht, sondern sie sind vielmehr definiert als #define sbi(x, y) x |= (1 << (y)) etc. Bei entsprechend passenden Operanden und eingeschalteter Optimierung können sie in der Tat in SBI/CBI-Befehle optimiert werden, aber der Benutzer sollte sich halt über die Randbedingungen im Klaren sein. Daher denken wir, daß das explizite Aufschreiben des entsprechenden C-Codes diesen Denkvorgang eher anstößt als das blinde Eintippen von sbi() oder cbi(). Das mit dem <avr/signal.h> hatte ich natürlich übersehen. Allerdings spuckt der Compiler eigentlich laut und deutlich Warnungen aus, wenn man das vergißt...
@Joerg: <avr/signal.h> war ja eingebunden, aber trotzdem hab ich im AVR-Studio nur leere Interruptvektoren gesehen. Ich such grad etwas rum und finde die Definition von PORTB2 nicht.? Vielleicht noch als Hinweis, im Moment wird das Ganze zwar auf einem ATMega128 entwickelt, soll aber spaeter auch auf einem ATMega103 laufen. Jens
aha. danke an euch beide für die aufklärung. letztes semester war outp und sbi noch gang und gebe auf der uni. mal schaun ob das dieses semester noch immer so ist. :)
> Ich such grad etwas rum und finde die Definition von PORTB2 nicht.? $ grep PORTB2 /usr/local/avr/include/avr/* /usr/local/avr/include/avr/portpins.h:# define PORTB2 PB2 > ...im Moment wird das Ganze zwar auf einem ATMega128 entwickelt, > soll aber spaeter auch auf einem ATMega103 laufen. Dann nimm doch gleich den 128 im M103C-Modus (ist ja der Auslieferungszustand).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.