Forum: Compiler & IDEs Taster abfragen - LED anschalten


von Dietmar P. (dietmar2)


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:
1
#include <avr/io.h>
2
3
void init(void);
4
5
int main(void)
6
{  
7
  
8
  init();       // Ports initialisieren
9
10
  while(1){
11
12
   if (PINA & (1 << PA0)){         // Taste 1 gedrückt
13
     PORTA &= ~(1<<3);             // LED PORTA - Pin 4 an
14
   }
15
16
  for(;;);
17
}//main
18
19
20
21
void init()
22
{
23
 
24
//PORTA auf Ausgang
25
    DDRA = 0xff;   
26
27
//  PORTA - Bit 0, 1 und 2 auf Eingang
28
    DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));
29
 
30
//set all internal pullups
31
    PORTA=0xff;   // on
32
 }

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

von Stefan E. (sternst)


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

von Simon Roith (Gast)


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);
        }
}

von Dietmar P. (dietmar2)


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

von Simon Roith (Gast)


Lesenswert?

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

von Dietmar P. (dietmar2)


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?

von Karl H. (kbuchegg)


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?

von Dietmar P. (dietmar2)


Lesenswert?

Das ist ein Atmega 32.

Gruß

von Simon Roith (Gast)


Lesenswert?

Hast du den Taster mit nem Pull-Down Widerstand versehen?

von Dietmar P. (dietmar2)


Lesenswert?

Nein, nicht extern, sondern intern mit:

//  PORTA=0xff;   // on

von Karl H. (kbuchegg)


Lesenswert?

Dietmar P. schrieb:
> Das ist ein Atmega 32.

OK.
Port A ist dort der ADC.

Hast du AVcc, AGND beschaltet?

von Simon Roith (Gast)


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 %

von Simon Roith (Gast)


Lesenswert?

oder seh ich das jetzt falsch?

von Karl H. (kbuchegg)


Lesenswert?

Simon Roith schrieb:
> oder seh ich das jetzt falsch?

Nö.
Hast du richtig gesehen.

Mal sehen, obs das war.

von Dietmar P. (dietmar2)


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?

von Karl H. (kbuchegg)


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?

von Dietmar P. (dietmar2)


Lesenswert?

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

von Simon Roith (Gast)


Lesenswert?

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

Poste mal deinen code bitte

von Dietmar P. (dietmar2)


Lesenswert?

Hallo Simon,

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

main.c:
1
// Steuerprogramm für Anzeigetableau
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <avr/pgmspace.h>
6
7
#ifndef F_CPU
8
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
9
#endif
10
11
#include "util/delay.h"
12
#include "taster.h"
13
14
15
//********************* internal functions
16
void init(void);
17
18
19
int main(void)
20
{  
21
  
22
  //*************** the global init
23
  init();          // Ports, etc inittialisieren
24
  
25
26
  // ***** HAUPTROUTINE ******
27
28
  while(1){
29
30
  _delay_ms(0.5); // Verzögerung 
31
32
      taster_abfrage();
33
34
  }  //while 
35
36
 
37
}//main
38
39
40
//**********************************************************************
41
//**********************  INITIALIZATION     ***************************
42
//**********************************************************************
43
44
void init()
45
{
46
 
47
  // PORTS auf Ausgang
48
  DDRA = 0xff;
49
  
50
  // PORTA - Bit 0, 1 und 2 auf Eingang
51
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));
52
 
53
  //set all internal pullups
54
  PORTA=0xff;   // on
55
56
57
}// init()

und hier die Tasterabfrage, taster.c:
1
// Abfrage der Taster
2
3
#include <avr/io.h>
4
#include "taster.h"
5
6
void taster_abfrage(void) 
7
{
8
9
  if (bit_is_set (PINA, PINA0)){  // Taste 1 gedrückt
10
      PORTA &= ~(1<<4);            // PortA Pin4 auf low, LED an
11
      }
12
13
} // 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.

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.
1
#include <avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
5
#endif
6
7
#include <util/delay.h>
8
9
int main(void)
10
{  
11
  DDRA = 0xff;                                         // Port A, alles auf Ausgang
12
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));   // bis auf die Tastereingaenge
13
  PORTA = ( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2);      // Pullups an den Tastern ein
14
15
  while(1) {
16
    _delay_ms(0.5); // Verzögerung 
17
18
    if( PINA & ( 1 << PINA0 ) )
19
      PORTA |= ( 1 << PA4 );
20
    else
21
      PORTA &= ~( 1 << PA4 );
22
  }
23
}

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.

von Bernd N (Gast)


Angehängte Dateien:

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.
1
int main (void)
2
{
3
    PORTD = 0xFF;                                // Pullups an PortD ON
4
5
    myLED_PIN = isOutput;
6
    myKey_PIN = isInput;
7
8
    for (;;) {
9
        if (myKey == isPressed) {
10
            myLED = ON;
11
        } else {
12
            myLED = OFF;
13
        }
14
    }
15
}

Das kann man besser lesen oder ?

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

von Dietmar P. (dietmar2)


Lesenswert?

Danke für Eure Ratschläge,
hat mir schon weiter geholfen.

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

Gruß
Dietmar

von Holger Steiger (Gast)


Lesenswert?

Hi,
ich habe noch eine andere Lösung der Aufgabe, sie setzt allerdings 
voraus, dass an den restlichen PortPins nichts drangeschaltet ist (der 
Taster ist hier an PIN0 und die LED an PIN1):

#include <avr/io.h>
#include <util/delay.h>

int main (void) {

  DDRB  = 0xFE;
  PORTB = 0x01;

  uint8_t temp = 1;

  while(1) {
    temp = PINB; //das funktioniert
    temp <<= 1;
    temp |= 1 << PB0;
    PORTB = temp;
  }

  /* wird nie erreicht */
  return 0;
}

MfG
Holger Steiger

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.