mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitfolgen generieren


Autor: Stefan Ruff (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 (;;)
     ;

Autor: Stefan Ruff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Joerg

Werd mich jetzt mal mit den ganzen Vorschlaegen auseinandersetzen.
Vielen Dank schon mal.

Mfg Stefan

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas K (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg Wunsch:
Wo steht denn, dass man sbi usw. nicht mehr verwenden sollte?
Und wieso outb? dachte es heißt outp?

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Thomas K (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. :)

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.