Hallo zusammen,
ich habe eine recht einfache Anforderung an einen Atmega 8. Ich habe 11
Taster als Eingänge und 11 Relaisausgänge.
Eingäng sind PD0 bis PD7 und PC4 bis PC6
Ausgänge sind PB0 bis PB7 und PC0 bis PC2
Wird ein Taster gedrückt soll der Ausgang für 10 Sekunden High-Level
führen. Das ist eigendlich schon die ganze Aufgabe.
Ich frage jeden Eingang in der main ab und setzte die Bit in der ISR.
Vielleicht findet jemand einen Fehler. Ich weiß nicht wo ich den Fehler
weiter suchen soll. Vielleicht hat ja jemand eine Idee...
[Gebetsmühlenmodus]
- Globale Variablen, die im Hauptprogramm und in Interrupt Handlern
verwendet werden, müssen volatile deklariert sein...
- Zu einem Fehler gehört eine Fehlerbeschreibung. Du erzählst nur, dass
Du ein Problem hast, aber nicht, was genau nicht funktioniert...
[/Gebetsmühlenmodus]
Mäh wrote:
> bit_is_clear ist ein Makro, der beim Compilieren FEST eincompiliert> wird.>> Du musst aber eine Funktion haben, die die Bitauswahl ZUR LAUFZEIT> vornimmt.
Käse, bit_is_clear ist vollkommen ok.
Danke für eure schnellen Antworten.
Das habe ich vergessen zu erwähnen. Mit den Tastern also dein Eingängen
schalte ich Masse zum µC durch. Deshalb auch bit_is_clear
Beim Einschalten der Anordung, schaltet schon ohne Bestätigung eines
Tasters ein paar Augänge durch. Ich weiß nicht warum.
Sollte ich noch Pull-Up Widerstände an die Eingänge des µC anlöten?
Steve wrote:
> Das habe ich vergessen zu erwähnen. Mit den Tastern also dein Eingängen> schalte ich Masse zum µC durch. Deshalb auch bit_is_clear
Schön. So soll es auch sein.
> Beim Einschalten der Anordung, schaltet schon ohne Bestätigung eines> Tasters ein paar Augänge durch. Ich weiß nicht warum.>> Sollte ich noch Pull-Up Widerstände an die Eingänge des µC anlöten?
Du hast keine Pull-Ups aktiviert? Klar, dann kann alles Mögliche
passieren! Anlöten muss man da aber keine. Es reicht i.d.R. völlig aus,
die im AVR eingebauten einzuschalten...
> PORTC &= (0 << PC2);
...und lies Dir bitte mal den Artikel Bitmanipulation durch! So, wie
Du das da schreibst, passiert da was ganz anderes als das, was Du
willst!
So wie es aussieht, könnte auch die Lektüre des AVR-GCC-Tutorials
nicht verkehrt sein...
@Sven P.
Kann Deinen Hinweis jedoch nicht nachvollziehen.
Auf http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html
steht:
#define _BV (bit) (1 << (bit))
#include <avr/io.h>
Converts a bit number into a byte value.
Note:
The bit shift is performed by the compiler which then inserts the
result into the code. Thus, there is no run-time overhead when using
_BV().
#define bit_is_clear(sfr,bit) (!(_SFR_BYTE(sfr) & _BV(bit)))
Wie soll dann seine Bit-Zählschleife funktionieren?
@Mäh:
Bitte spiel einfach mal Präprozessor und schreib hin, was der
Präprozessor als Textersetzung bei der Expandierung der Makros
hinschreiben würde. Dann siehst Du auch, dass es gar kein Problem ist...
Mäh wrote:
> @Sven P.> Kann Deinen Hinweis jedoch nicht nachvollziehen.>> Auf http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html> steht:>> #define _BV (bit) (1 << (bit))> #include <avr/io.h>>> Converts a bit number into a byte value.
Richtig.
> Note:> The bit shift is performed by the compiler which then inserts the> result into the code. Thus, there is no run-time overhead when using> _BV().>> #define bit_is_clear(sfr,bit) (!(_SFR_BYTE(sfr) & _BV(bit)))>> Wie soll dann seine Bit-Zählschleife funktionieren?
Wenn 'bit' eine zur Übersetzungszeit bekannte Konstante ist, rechnet der
Kompiler das aus und gut. Wenns eine Variable ist, wird daraus:
Steve wrote:
> Beim Einschalten der Anordung, schaltet schon ohne Bestätigung eines> Tasters ein paar Augänge durch. Ich weiß nicht warum.
Resetbeschaltung? Abblockkondensatoren? Schaltplan?
http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf
Olli
Du meinst, da steht dann am Ende noch das "i", und somit wird es nicht
wegoptimiert? Hm, eigentlich logisch. Ich war jetzt davon ausgegangen,
dass da dann irgendein fester Default-Bytewert landet. Aber so fies ist
der Präprozesser dann wohl doch nicht. Da hab ich wohl zu pessimistisch
gedacht... :-/
Mäh wrote:
> Aber so fies ist> der Präprozesser dann wohl doch nicht.
Der Präprozessor ist überhaupt nicht "fies". Der macht nur ganz stur
Textersetzungen. Und wenn da ein i steht, dann bekommt der Compiler auch
ein i...
> PORTC &= (0 << PC2);>...und lies Dir bitte mal den Artikel Bitmanipulation durch! So, wie>Du das da schreibst, passiert da was ganz anderes als das, was Du>willst!
Steh ich auf dem Schlauch ??? Das müsste doch gehen, oder?
Die 0 wird verschoben, und alle anderen Bits des Bytes mit der 0 sind
auch 0. Also ist das Ergebnis auch 0. Somit werden durch das & alle Bits
gelöscht.
Du musst eine 1 verschieben und das verschobene Byte mit ~ invertieren.
Steve wrote:
>> PORTC &= (0 << PC2);>>...und lies Dir bitte mal den Artikel Bitmanipulation durch! So, wie>>Du das da schreibst, passiert da was ganz anderes als das, was Du>>willst!>>> Steh ich auf dem Schlauch ??? Das müsste doch gehen, oder?
Klar geht das. Es macht nur vermutlich nicht das, was Du willst. Denn
wenn das, was da passiert, von Dir beabsichtigt wäre, hättest Du
vermutlich einfach "PORTC = 0;" geschrieben...
Merke: Eine 0 kannst Du schieben, so oft Du willst, es bleibt eine Null!
Und "X & 0" ergibt immer 0...