Taster abfragen - LED anschalten

#1691033
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.
#1691051
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).
Gast #1691057
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);
        }
}
#1691191
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
#1691283
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?
Gast #1691431
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 %
#1692965
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.
#1692983
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.
#1692990
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.
Gast #1693805
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.
Angehängte Dateien:
Gast #5322237
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren