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]
bit_is_clear ist ein Makro, der beim Compilieren FEST eincompiliert wird. Du musst aber eine Funktion haben, die die Bitauswahl ZUR LAUFZEIT vornimmt.
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:
1 | #define bit_is_clear(sfr,bit) (!(_SFR_BYTE(sfr) & _BV(bit)))
|
2 | |
3 | int ergebnis, i; |
4 | ergebnis = bit_is_clear(PORTA, i); |
5 | |
6 | /* Ergibt: */
|
7 | ergebnis = !(PORTA & (1 << i)); |
Das ist vollkommen legitim. Muss der Übersetzer sich halt mal anstrengen, wie der dem AVR die Schieberei um 'i' Stellen verklickert.
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... :-/
Ok, danke für die Hinweise! Super eigentlich -- das Teil ist besser als ich dachte. :-)
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...
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.