Forum: Mikrocontroller und Digitale Elektronik Probleme bei einfachem Atmega Programm


von Steve (Gast)


Angehängte Dateien:

Lesenswert?

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...

von Johannes M. (johnny-m)


Lesenswert?

[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]

von Mäh (Gast)


Lesenswert?

bit_is_clear ist ein Makro, der beim Compilieren FEST eincompiliert 
wird.

Du musst aber eine Funktion haben, die die Bitauswahl ZUR LAUFZEIT 
vornimmt.

von Sven P. (Gast)


Lesenswert?

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.

von Steve (Gast)


Lesenswert?

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?

von Johannes M. (johnny-m)


Lesenswert?

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...

von Johannes M. (johnny-m)


Lesenswert?

> 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...

von Mäh (Gast)


Lesenswert?

@Sven P.
Danke für den Hinweis!

von Mäh (Gast)


Lesenswert?

@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?

von Johannes M. (johnny-m)


Lesenswert?

@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...

von Sven P. (Gast)


Lesenswert?

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.

von Olli R. (omr) Benutzerseite


Lesenswert?

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

von Mäh (Gast)


Lesenswert?

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... :-/

von Mäh (Gast)


Lesenswert?

Ok, danke für die Hinweise!

Super eigentlich -- das Teil ist besser als ich dachte. :-)

von Johannes M. (johnny-m)


Lesenswert?

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...

von Steve (Gast)


Lesenswert?

> 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?

von Mäh (Gast)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

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
Noch kein Account? Hier anmelden.