mikrocontroller.net

Forum: Compiler & IDEs Taster abfragen - LED anschalten


Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so langsam drehe ich am Rad und bitte um Hilfe. Habe offensichtlich 
einen Grundsatz-/Verständnisfehler in meiner "Denke".

Ich möchte einfach nur, wenn eine Taste gedrückt ist eine LED leuchten 
lassen.
Bin auf dem Gebiet C und µC newbie.

Belegung:
Taste: PORTA Pin 0
LED:   PORTA Pin 4

Code:
#include <avr/io.h>

void init(void);

int main(void)
{  
  
  init();       // Ports initialisieren

  while(1){

   if (PINA & (1 << PA0)){         // Taste 1 gedrückt
     PORTA &= ~(1<<3);             // LED PORTA - Pin 4 an
   }

  for(;;);
}//main



void init()
{
 
//PORTA auf Ausgang
    DDRA = 0xff;   

//  PORTA - Bit 0, 1 und 2 auf Eingang
    DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));
 
//set all internal pullups
    PORTA=0xff;   // on
 }

Ich weiß, dass es Handbücher gibt, aber ich finde keine Lösung und bitte 
um Hilfe.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soll die LED beim Loslassen der Taste auch wieder aus gehen, oder nicht?

Bitte bei Fragen immer den echten Code posten. Den Code oben kannst du 
gar nicht ausprobiert haben, denn der wird wegen einer fehlenden Klammer 
gar nicht compilieren. Und da wir nicht wissen, wo diese zusätzliche 
Klammer war/ist, wissen wir auch nicht, ob die zweite Endlosschleife 
tatsächlich innerhalb der anderen war/ist (böse), oder dahinter 
(überflüssig, aber harmlos).

Autor: Simon Roith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

probiers mal damit:

#include <avr/io.h>

void init(void)
{
       DDRA = 0b00010000;  // PB0 = Eingang, PA4 = Ausgang
       PORTB = 0;
}

int main (void)

    init(); //Aufruf Unterprogramm

while(1)
{
      if (bit_is_set (PINA, PINA0))
         {
           PORTA |= (1<<PA4);
         }

     else
        {
          PORTA &=~ (1<<PA4);
        }
}

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan:

ok, nur mein gesamter Originalcode ist zu lang und deshalb habe ich die 
wesentlichen Stellen, wie ich meinte herausgezogen.
Wollte nur das Prinzip darstellen.

@ Simon:

Super, danke,
das war die Lösung. Mit dem bit_is_set Ausdruck hat es funktioniert, ist 
auch einfacher.

Gruß
Dietmar

Autor: Simon Roith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nichts zu danken :)
Bin zwar kein Profi aba damit kenn ich mich schon aus^^

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Schönheitsfehler: Wenn ich den Taster drücke, dann geht die LED an.
Aber wenn ich den Taster loslasse, dann flimmert die LED, geht auch mal 
aus, aber nicht gleich, oder sie flimmert auch weiter.
Allerdings habe ich für alles den PORTA nehmen müssen.

Definition des PORTA:

  // PORTS auf Ausgang
  DDRA = 0xff;

  // PORTA - Bit 0, 1 und 2 auf Eingang
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));

   //set all internal pullups
//  PORTA=0xff;   // on


Ist da was falsch?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:
> Nachtrag:
>
> Schönheitsfehler: Wenn ich den Taster drücke, dann geht die LED an.
> Aber wenn ich den Taster loslasse, dann flimmert die LED, geht auch mal
> aus, aber nicht gleich, oder sie flimmert auch weiter.
> Allerdings habe ich für alles den PORTA nehmen müssen.

Welcher Prozessor?

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein Atmega 32.

Gruß

Autor: Simon Roith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du den Taster mit nem Pull-Down Widerstand versehen?

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, nicht extern, sondern intern mit:

//  PORTA=0xff;   // on

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:
> Das ist ein Atmega 32.

OK.
Port A ist dort der ADC.

Hast du AVcc, AGND beschaltet?

Autor: Simon Roith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du das so schreibst:

// PORTA=0xff //on  dann ist das Auskommentiert! und hat keine funktion.


nimm die beiden doppel Slasch weg oder
Klemm vor den taster einen Pull-Down hin und es funkt zu 100 %

Autor: Simon Roith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder seh ich das jetzt falsch?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon Roith schrieb:
> oder seh ich das jetzt falsch?

Nö.
Hast du richtig gesehen.

Mal sehen, obs das war.

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtig, da habe ich den Wald vor lauter Bäumen wieder einmal nicht 
gesehen.

ABER:

Das Geflimmer bleibt, habe es soeben auch mit externen Pullup's 
probiert,
auch keine Veränderung, leider.

Noch 'ne Idee?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:
> Richtig, da habe ich den Wald vor lauter Bäumen wieder einmal nicht
> gesehen.
>
> ABER:
>
> Das Geflimmer bleibt, habe es soeben auch mit externen Pullup's
> probiert,
> auch keine Veränderung, leider.
>
> Noch 'ne Idee?

OK.
Dann nochmal die Frage:

AVcc und AGND sind beschaltet?

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVCC ist +5 V und
AGND ist Masse, -, oder 0

Autor: Simon Roith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du jetzt über software pull up gemacht und mit nem Pull-Up 
widerstand?

Poste mal deinen code bitte

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Simon,

anbei nochmals den Code (vereinfacht), kam gestern nicht mehr dazu:

main.c:
// Steuerprogramm für Anzeigetableau

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#ifndef F_CPU
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
#endif

#include "util/delay.h"
#include "taster.h"


//********************* internal functions
void init(void);


int main(void)
{  
  
  //*************** the global init
  init();          // Ports, etc inittialisieren
  

  // ***** HAUPTROUTINE ******

  while(1){

  _delay_ms(0.5); // Verzögerung 

      taster_abfrage();

  }  //while 

 
}//main


//**********************************************************************
//**********************  INITIALIZATION     ***************************
//**********************************************************************

void init()
{
 
  // PORTS auf Ausgang
  DDRA = 0xff;
  
  // PORTA - Bit 0, 1 und 2 auf Eingang
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));
 
  //set all internal pullups
  PORTA=0xff;   // on


}// init()


und hier die Tasterabfrage, taster.c:

// Abfrage der Taster

#include <avr/io.h>
#include "taster.h"

void taster_abfrage(void) 
{

  if (bit_is_set (PINA, PINA0)){  // Taste 1 gedrückt
      PORTA &= ~(1<<4);            // PortA Pin4 auf low, LED an
      }

} // Taster-Abfrage


Ich hoffe das passt so.
Ist da ein grundsätzlicher Fehler drin? Vor dem bit_is_set hatte ich da 
folgende Codezeile:

  if (!(PINA&(1<<PINA1));{

Ist das richtiger?? Mein Taster geht geschlossen auf GND.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:

> void taster_abfrage(void)
> {
>
>   if (bit_is_set (PINA, PINA0)){  // Taste 1 gedrückt


wenn deine Taster auf GND schalten, dann kriegst du bei gedrückten 
Taster aber im Pin eine 0 und keine 1.

D.h.
  if( bit_is_clear (PINA, PINA0) ) {

ausserdem solltest du noch einen else Zweig vorsehen, der die LED bei 
nicht gedrückten Taster auch wieder zurückschaltet.


> Ist da ein grundsätzlicher Fehler drin? Vor dem bit_is_set hatte ich da
> folgende Codezeile:
>
>   if (!(PINA&(1<<PINA1));{

Da ist ein Strichpunkt zuviel.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nichts gegen viele Funktionen und Aufteilung in mehrere Files. Aber 
gerade am Anfang schafft dir das mehr Probleme, als es dir bringt. Die 
verringerte Übersicht lässt dich Fehler begehen, die du nicht bemerkst

Also übertreibe es nicht, und schreibe deine ersten Programme kurz und 
knackig. Du bist noch nicht so weit, physisch längere Programme zu 
überblicken ohen ständig scrollen und Fenster wechseln zu müssen. Sei 
froh, wenns zur Zeit auch noch so geht.
#include <avr/io.h>

#ifndef F_CPU
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
#endif

#include <util/delay.h>

int main(void)
{  
  DDRA = 0xff;                                         // Port A, alles auf Ausgang
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));   // bis auf die Tastereingaenge
  PORTA = ( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2);      // Pullups an den Tastern ein

  while(1) {
    _delay_ms(0.5); // Verzögerung 

    if( PINA & ( 1 << PINA0 ) )
      PORTA |= ( 1 << PA4 );
    else
      PORTA &= ~( 1 << PA4 );
  }
}

Ist 3-mal so kurz und gibt dir für den Anfang genug Stoff zum 
experimentieren. Gerade am Anfang ist es wichtig, dass du nicht die 
Übersicht verlierst, was du wo programmiert hast. Bei 10 oder 20-Zeilern 
ist noch keine Gefahr, dass du durch Nicht-Aufteilen in Funktionen oder 
Files die Übersicht verlierst, ganz im Gegenteil: Halte dir die Dinge 
beisammen, so dass du möglichst das komplette Programm in einer 
Bildschirmseite unterbringen kannst.

Autor: Bernd N (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die Schreibweise beim AVRGCC ist einfach grausig aber man kann sich das 
Leben erheblich leichter machen wenn man ein paar wenige Macros 
verwendet.

Diese Macros wurden hier in anderen Threads vorgestellt und erklärt wenn 
du dich näher damit befassen möchtest.
int main (void)
{
    PORTD = 0xFF;                                // Pullups an PortD ON

    myLED_PIN = isOutput;
    myKey_PIN = isInput;

    for (;;) {
        if (myKey == isPressed) {
            myLED = ON;
        } else {
            myLED = OFF;
        }
    }
}

Das kann man besser lesen oder ?

Im Anhang das passende *.h file. Achtung, habe eine andere PIN Belegung 
verwendet.

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für Eure Ratschläge,
hat mir schon weiter geholfen.

Für einen Einsteiger ist es halt immer etwas schwer.

Gruß
Dietmar

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.