mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Taster maskieren


Autor: Jens1993 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal wieder eine unbeliebte Anfängerfrage....
Ich benutze ein STK500.
Unten sind Auszüge eines Programms. Zum einen die Init und zum anderen 
dass eigentliche Programm.
Die LED0 am PORTB soll bei tastendruck leuchten, bei wiederloslassen 
soll sie wieder ausgehen.
Mein Problem liegt bei der "if" Anweisung.

Es wird ja PIND mit (1<<PD0) "verundet". D.h, der taster PD0 wird 
maskiert. Ich verstehe nun nicht, auf was die "if" anweisung "abfragt". 
Seither kenne ich nur if Anweisung, wie z.B.

    if(a = 1)
      {
      }

hier wird ja klar abgefragt, ob a = 1 ist. Aber auf was fragt die if 
Anweisung in meim Programm ab?
Ich glaub, meine frage ist nicht leicht zu verstehen, aber vllt kann mir 
ja jemand helfen.
Danke!

        DDRA = 0xFF;
  DDRB = 0xFF;
  DDRC = 0xFF;
  DDRD = 0xFE;

  PORTA = 0xFF;
  PORTB = 0xFF;
  PORTC = 0xFF;
  PORTD = 0xFF;


while(1)
  {
    if(!(PIND & (1<<PD0)))
    {
      PORTB = ~1;
    }
    else
    {
      PORTB = 0xFF;
    }


  }

  return(0);

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens1993 schrieb:

>     if(a = 1)
>       {
>       }
>
> hier wird ja klar abgefragt, ob a = 1 ist.

Nein. Klassischer Programmierfehler.

Rest: Bitmanipulation

Autor: Jens1993 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups sorry

meinte natürlich

    if(a == 1)
    {
    }

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>     if(!(PIND & (1<<PD0)))

ist identisch

    if( (PIND & (1<<PD0)) == 0 )

PIND ist ein 8-bittiges SFR special function register bei AVR µCs.
& (1<<PD0) bildet eine Bitmaske für das PD0.te Bit.
Die Bedingung testet also ob das PD0.te Bit in PIND nicht gesetzt ist.

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens1993 schrieb:

> Aber auf was fragt die if Anweisung in meim Programm ab?

In C ist 0 false und alles andere true, also sind
if (FOO)
if (FOO != 0)

äquivalent.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PD0 ist auf 0 definiert (#define)
x sei 0 oder 1

Wenn PIND gleich xxxxxxx0 binär dann ist das Ergebnis der Berechnung 
00000000 binär bzw. 0 dezimal und die if-Bedingung wahr

wenn PIND gleich xxxxxxx1 binär dann ist das Ergebnis der Berechnung 
00000001 binär bzw. 1 dezimal und die if-Bedingung falsch

Autor: Jens1993 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke erstmal!

dann versuch ich das mal als Bitmuster darzustellen

     if( (PIND & (1<<PD0)) == 0 )

wenn PD0 gedrückt ergibt sich folgendes  Muster

PIND     =     11111110
                  &
(1<<PD0) =     00000001

ergebnis =     00000000

wenn also      ergebnis == 0

dann           PORTB = ~1


so müsste es doch dann aussehen?!?

Autor: Barny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mir außerdem diverse Aktionen zum entprellen der Tasten 
überlegen.
http://www.mikrocontroller.net/articles/Entprellung

Ein kleiner Tipp am Rande:
Ich verwende Bitoperationen wie (PIND & (1<<PD0)) nur beim 
Initialisieren des Prozessors um eine bessere Übersichtlichkeit zu 
haben.

Im Programm selbst verwende ich Deffinitionen der Bitmuster.
Denn wenn einmal nicht optimiert werden sollte, gehen bei jedem 
Durchgang ein Takt für's shiften und einer für's verunden drauf.

Dass steht zum Beispiel in meinen Deffinitionsheader:

Generelle Deffiniton der Bitmuster:
//StdDefEx.h
#ifndef stddefex_h
#define stddefex_h

#define Bit0    0x01
#define Bit1    0x02
#define Bit2    0x04
#define Bit3    0x08
#define Bit4    0x10
#define Bit5    0x20
#define Bit6    0x40
#define Bit7    0x80

#define Clear_Bit0    0xFE
#define Clear_Bit1    0xFD
#define Clear_Bit2    0xFB
#define Clear_Bit3    0xF7
#define Clear_Bit4    0xEF
#define Clear_Bit5    0xDF
#define Clear_Bit6    0xBF
#define Clear_Bit7    0x7F

#ifndef NULL
#define NULL    0x00
#endif

#ifndef TRUE
#define TRUE    0x01
#endif

#ifndef FALSE
#define FALSE   0x00
#endif

typedef union {
        unsigned short us;
        struct
    {
                unsigned char uch_l;
                unsigned char uch_h;
        };
} split_short;
#endif /*stddefex_h*/
Und zum Beispiel dass im Projektheader;
//Main.h
#ifndef main_h
#define main_h

    //////////////////////
  //  Port Deffinition // 
////////////////////////

#define DEF_PORT_LED        PORTA

#define DEF_PIN_LED         Bit0
#define DEF_PIN_LED_CLEAR   Clear_Bit0

    ////////////////////////////////////
  //  Deffinition für LED-Steuerung // 
/////////////////////////////////////

#define LEDan   (DEF_PORT_LED &= DEF_PIN_LED_CLEAR) // LED an   -> invertierte logik 
#define LEDaus  (DEF_PORT_LED |= DEF_PIN_LED)       // LED aus  -> invertierte logik 
#define IsLEDaus    ((DEF_PORT_LED & DEF_PIN_LED)==DEF_PIN_LED) //Überprüfen ob die LED aus ist -> if(IsLEDaus)
#define IsLEDan  ((DEF_PORT_LED & DEF_PIN_LED)==0) //Überprüfen ob die LED an ist -> if(IsLEDan)
#endif /*main_h*/

Damit kann ich im Projekt über LEDan; und LEDaus; die LED an und aus 
schalten, ohne mich groß um Bitmanipulationen sorgen machen zu müssen.
Außerdem hat man den Vorteil, dass wenn sich etwas an der Hardware 
ändert, die Änderungen_ nur _ein mal_ an _einer Stelle durchgeführt 
werden müssen.
Man muß also nicht gleich den gesammten Quellcode durchsuchen war zu 
Fehler führen kann.
Dass gleiche Prinzip kannst du auch bei der Auswertung der Tasten 
anwenden.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Exaktemente.

[Goldwaageauspackmodus an]
> wenn PD0 gedrückt ergibt sich folgendes  Muster
> PIND     =     11111110

NUR, wenn es ein active-low angeschlossener Taster ist. Was das ist, 
steht im AVR-GCC-Tutorial

Gleich merken: Fragen zu Sourcecode sind im µC-Bereich meist von der 
Schaltung abhängig. Deshalb lieber Schaltplan einmal zu oft an die Frage 
anhängen als einmal zu wenig...
[Goldwaageauspackmodus aus]

Autor: Jens1993 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann wär ein weiteres meiner Rätsel gelöst!
Danke an alle!
Gruß

Autor: Barny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jens1993

Fast richtig.

~1 ist quasi ein "Wechselschalter"
Wenn Bit0 gerade 0 ist, wird es 1, wenn es gerade 1 ist, wird es 0.

Wenn du gezielt, unabhängig vom aktuellen Zustand schalten willst, 
verwende:
PORTB |= 0x01;
und
PORTB  &= 0xFE;

Autor: Barny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe vergessen zu schreiben dass der angefügte Code nur aus 
Codeausschnitten besteht.
Im eigentlichen Projekt sind ein paar Includes und Deffinitonen mehr 
drinnen ;)

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.