Forum: Mikrocontroller und Digitale Elektronik Fehler im Unterprogramm - Verständnisfrage (Taster entprellen)


von Toni (Gast)


Lesenswert?

Hi Leute,
hier geht es im Grunde um eine Taster-Erkennung und Entprellung. Die 
Tasten werden einzeln auf eine fallende Flanke getestet, damit eine 
Fehlfunktion bei der Betätigung beider Taster vermieden wird.
Im debugger hat das Programm funktioniert, Praktisch auf dem Steckbrett 
allerdings nicht. Ich konnte herausfiltern, dass sich der Fehler beim 
Aufruf der Funktion "Taster-entprellen" ereignet. Ich kann aber leider 
nicht nachvollziehen, warum. Habe es mit allen Optimierungen probiert -> 
ohne Erfolg. Ganz unten habe ich die "Optimierte" und funktionierden 
Datei "IO.c" angehängt.
Vielleicht sieht ja jemand auf den ersten Blick das Problem, bzw. den 
Fehler.
Vielen Dank.

Main.c
1
// *************INCLUDE ***************
2
#include "Include.h"
3
#include "globals.h"
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
#include <stdint.h>
8
#include <avr/eeprom.h>
9
10
// Prototypen
11
uint8_t Taster_einlesen(void);
12
void Taster_entprellen(void);
13
14
int main(void)
15
{  
16
  StatusObergrenze = 0;
17
  StatusUntergrenze = 0;
18
  GlobalWertTaster = 0;
19
  
20
  // IO-Einstellen
21
  IO_DDR |= (1<<LED_Obergrenze) | (1<<LED_Untergrenze);
22
  IO_PORT |= (1<<TASTER_Obergrenze) | (1<<TASTER_Untergrenze);
23
  
24
  //endlos
25
  while(1)
26
  {
27
  uint8_t Taster_Status = Taster_einlesen();
28
  if(Taster_Status == 1)
29
    IO_PORT ^= (1<<LED_Untergrenze);
30
  if(Taster_Status == 2)
31
    IO_PORT ^= (1<<LED_Obergrenze);
32
  if(Taster_Status == 3)
33
    IO_PORT |= (1<<LED_Untergrenze)| (1<<LED_Obergrenze);
34
  }

IO.c
1
uint_8t Taster_entprellen(void)
2
{
3
  uint8_t temp, Zustand;
4
  Zustand = ~IO_PIN;
5
  Zustand &= ((1<<TASTER_Obergrenze) | (1<<TASTER_Untergrenze));
6
  _delay_ms(10);
7
  temp = ~IO_PIN;
8
  temp &= ((1<<TASTER_Obergrenze) | (1<<TASTER_Untergrenze));
9
  if (temp == Zustand)
10
    return temp;  
11
  else
12
    return 0;
13
}
14
15
uint8_t Taster_einlesen(void)
16
{  
17
  uint8_t Taster_Variable = Taster_entprellen;
18
  
19
  //beide Taster
20
  if ((Taster_Variable == ((1<<TASTER_Untergrenze)|(1<<TASTER_Obergrenze))) && !(GlobalWertTaster & 1))
21
  {
22
    _delay_ms(500);  // Wartezeit
23
    Taster_Variable = Taster_entprellen;
24
    if (Taster_Variable == ((1<<TASTER_Untergrenze)|(1<<TASTER_Obergrenze)))
25
    {
26
  GlobalWertTaster = Taster_Variable | 1;
27
  return 3;
28
    }
29
        return 0;
30
   }
31
        
32
  if (!(GlobalWertTaster & 1))
33
    {
34
  // Linker Taster
35
  if((!(Taster_Variable & (1<<TASTER_Untergrenze))) && (GlobalWertTaster & (1<<TASTER_Untergrenze)) && !(GlobalWertTaster & 1))
36
  {
37
    GlobalWertTaster = 0;
38
    return 1;
39
  }
40
  // Rechter Taster
41
  if((!(Taster_Variable & (1<<TASTER_Obergrenze))) && (GlobalWertTaster & (1<<TASTER_Obergrenze)) && !(GlobalWertTaster & 1))
42
    {
43
      GlobalWertTaster = 0;
44
      return 2;
45
    }
46
  GlobalWertTaster = Taster_Variable;
47
  }
48
  
49
  if ((GlobalWertTaster & 1) && Taster_Variable == 0)
50
    GlobalWertTaster = 0;
51
  
52
  return 0;
53
}

Funktionierde IO.c
1
uint8_t Taster_einlesen(void)
2
{  
3
  uint8_t temp, Taster_Variable; //geändert
4
  Taster_Variable = ~IO_PIN; //geändert
5
  _delay_ms(10); //geändert
6
  temp = ~IO_PIN; //geändert
7
  if (temp == Taster_Variable) //geändert
8
    Taster_Variable &= ((1<<TASTER_Obergrenze) | (1<<TASTER_Untergrenze)); //geändert
9
  else //geändert
10
    return 0; //geändert
11
  
12
  //beide Taster
13
  if ((Taster_Variable == ((1<<TASTER_Untergrenze)|(1<<TASTER_Obergrenze))) && !(GlobalWertTaster & 1))
14
  {
15
    _delay_ms(500);  // Wartezeit
16
    Taster_Variable = Taster_entprellen;
17
    if (Taster_Variable == ((1<<TASTER_Untergrenze)|(1<<TASTER_Obergrenze)))
18
    {
19
  GlobalWertTaster = Taster_Variable | 1;
20
  return 3;
21
    }
22
        return 0;
23
   }
24
        
25
  if (!(GlobalWertTaster & 1))
26
    {
27
  // Linker Taster
28
  if((!(Taster_Variable & (1<<TASTER_Untergrenze))) && (GlobalWertTaster & (1<<TASTER_Untergrenze)) && !(GlobalWertTaster & 1))
29
  {
30
    GlobalWertTaster = 0;
31
    return 1;
32
  }
33
  // Rechter Taster
34
  if((!(Taster_Variable & (1<<TASTER_Obergrenze))) && (GlobalWertTaster & (1<<TASTER_Obergrenze)) && !(GlobalWertTaster & 1))
35
    {
36
      GlobalWertTaster = 0;
37
      return 2;
38
    }
39
  GlobalWertTaster = Taster_Variable;
40
  }
41
  
42
  if ((GlobalWertTaster & 1) && Taster_Variable == 0)
43
    GlobalWertTaster = 0;
44
  
45
  return 0;
46
}

von Peter II (Gast)


Lesenswert?

> uint8_t Taster_Variable = Taster_entprellen;

was soll das darstellen?

von Toni (Gast)


Lesenswert?

Sorry, sollte der Aufruf des Unterprogrammes sein...
1
uint8_t Taster_Variable = Taster_entprellen();

Der Prototyp im Main habe ich auch falsch übernommen...

[c]
// Prototypen
uint8_t Taster_einlesen(void);
uint8_t Taster_entprellen(void);
[c]

von Peter D. (peda)


Lesenswert?

Toni schrieb:
> _delay_ms(500);  // Wartezeit

Oh Gott.
Ein Gamer drückt in dieser elend langen Zeit 5 Tasten, die dann nicht 
bearbeitet werden.

Es gibt bereits gut funktionierende Entprellroutinen mit Timerinterrupt.
Man muß nicht alles selber nachentwickeln.

von Toni (Gast)


Lesenswert?

Man, Leute.
Ich habe eine konkrete Frage gestellt und möchte dazu eine Antwort. Ich 
habe den Fehler eingegrenzt um die Einarbeitung für euch so kurz wie 
möglich zu gestalten. Es hat mit der Tastenerkennung und entprellerei 
nichts zu tun, es handelt sich - so vermute ich - um ein Problem der 
Werte-Übergeberei.
Entweder ihr habt den Willen mal einen Blick darüber zu werfen, oder 
lasst es einfach bleiben und faselt nicht irgendwelchen schwachsinnigen 
Brei rum.
Danke.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Toni schrieb:
> und faselt nicht irgendwelchen schwachsinnigen
> Brei rum.

mit solchen Kommentaren förderst du nicht grade die Hilfsbereitschaft 
derjenigen, die sich deines Problems annehmen wollen

von Peter D. (peda)


Lesenswert?

Du kannst gerne weiter wütend mit den Füßen auf den Boden stampfen, nur 
wird das nichts bringen.

Zuverlässiges Entprellen schüttelt man nicht so einfach aus dem Ärmel 
und erst recht nicht das Unterscheiden des einzelnen vom gleichzeitigen 
Drücken.
Du kannst zwar im Simulator 2 Pins gleichzeitg setzen, nicht aber im 
realen Leben.

Deine überlangen Zeilen sind ein Graus. Eingebetteter Code sollte 
wenigstens ohne Scrollen lesbar sein.
Ansonsten Code compilierbar als Anhang. Bzw. das ist eigentlich immer 
die bessere Form.

von Toni (Gast)


Angehängte Dateien:

Lesenswert?

Keine Sorge, ich bin nicht wütend. Nur dieses rechthaberische und 
wichtig-getue geht mir sowas von gegen den Strich. Einfache Frage - 
einfache Antwort ohne Belehrungen oder sonstiges.

Und um das zuverlässige Erkennen von 2 Tasten zu erkennen, habe ich mir 
leider Gedanken gemacht, dass konnte - so glaube ich beim schnellen 
überfliegen entdeckt zu haben - kein fertiger Tastercode. Diesbezüglich 
wird bei einem einzelnen Tasterdruck auf die fallende Flanke reagiert, 
wenn 2 gedrückt werden auf die steigende.

Aber um nicht allzu viel rumzulabern, Code im Anhang. Ich hoffe, ich 
habe keine Fehler eingebaut und nichts vergessen.

von Peter D. (peda)


Lesenswert?

Toni schrieb:
> Und um das zuverlässige Erkennen von 2 Tasten zu erkennen, habe ich mir
> leider Gedanken gemacht, dass konnte - so glaube ich beim schnellen
> überfliegen entdeckt zu haben - kein fertiger Tastercode.

Beitrag "Universelle Tastenabfrage mit 2 Tastenerkennung"

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.