mikrocontroller.net

Forum: Compiler & IDEs Entprellung funktioniert nicht


Autor: Mathias O. (m-obi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

meine Entprellung funktioniert nicht, Funktion key_pressed_1 
funktioniert aber die andere key_pressed_2 nicht.
Woran kann das liegen?

#define Taster_2 (PIND&(1<<PD3))

uint8_t key_pressed_1(const volatile uint8_t *inputreg, uint8_t inputbit)
{
  static uint8_t last_state = 0;
 
  if (last_state==(*inputreg&(1<<inputbit)))
  {
    return 0;
  }
 
  _delay_ms(20);
 
  last_state=(*inputreg&(1<<inputbit));
 
 
  return ( *inputreg & (1<<inputbit) );
}
 
 

 uint8_t key_pressed_2(const volatile uint8_t *input)
{
  static uint8_t last_state = 0;
 
  if ( last_state == *input ) {
     return 0; 
  }
 
  _delay_ms(20);
 
  last_state = *input;
 
  return *input;
}



int main(void)
{

DDRD = 0b11100011;

while(1)
{                
if (key_pressed_1(&PIND,PD2))
PORTD ^= (1<<5);
          
if (key_pressed_2(Taster_2))
PORTD ^= (1<<6);
}
return 0;
}

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> uint8_t key_pressed_2(const volatile uint8_t *input)
> if (key_pressed_2(Taster_2))
> #define Taster_2 (PIND&(1<<PD3))

Ist Taster_2 ein const volatile uint8_t * ? Ich denke nicht!

PS: Mich würde stark wundern, wenn der Compiler da nicht meckert.

Autor: Mathias O. (m-obi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was denn???

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mathias Obetzhauser wrote:
> was denn???

Vorsicht Offtopic!

Der normale Entwicklungszyklus:

1. Unterlagen studieren
2. Rechenvorschrift ausdenken
3. Rechenvorschrift in Code pressen
4. Compiler Code auf formale Bugs checken lassen
5. Gesäuberten Code anderen vorlegen, um fettere Bugs zu finden
6. Automatische Tests ausführen
7. Interaktiv/Im System Debuggen

Warum diese Reihenfolge?

Die einzelnene Schritte sind mit steigendem Aufwand geordnet. Saubere 
Arbeit in den frühen Schritten reduziert den Aufwand in den späteren 
Schritten.

Mit der Anfrage inkl. Codefetzen steigt der OP in den Schritt 5 ein. 
Allerdings ist das kein gesäuberter Code. Der Compiler hätte in Schritt 
4 den Code angemostert. Abgesehen davon hat der OP 1. und 2. denjenigen 
vorenthalten, die für ihn "arbeiten sollen". Ein Projektleiter würde 
sagen, der OP hat "Resourcen verschwendet".

Die Idee für dieses Offtopic ist mir dadurch gekommen:

Lean coding
What's the cheapest way to get rid of bugs? Inspect code early and 
often.
By Jack Ganssle
http://www.embedded.com/design/212200181

Autor: Mathias O. (m-obi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit der Antwort kann ich recht wenig anfangen....


achja und der Compiler meckert nicht

Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
0. Anforderungen definieren (was soll der Code eigentlich genau machen?)

Juergen

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Juergen

Stimmt!

Autor: Mathias O. (m-obi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sind Entprell-Funktionen für Taster, wie gesagt die erste 
funktioniert aber die zweite nicht. Ich wollte es mit dem #define etwas 
vereinfachen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil durch dein falsches Makro für Taster_2 in key_pressed_2() nur ein 
uint8_t Wert ankommt. Diesen durch den Prototypen geschickt (gecastet) 
und mit dem Funktionscode als Pointer ausgewertet, ist ein Bug. Ein 
fetter Bug.

Autor: Mathias O. (m-obi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und wie kann man diesen Bug beseitigen, bin relativ neu in Sachen C.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. wrote:

> Mit der Anfrage inkl. Codefetzen steigt der OP in den Schritt 5 ein.
> Allerdings ist das kein gesäuberter Code.

Den Vortrag kannst du dir schenken, ist ja nicht der erste Thread des 
Posters, in dem ihm erklaert wird, wie man entwickelt...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lernen ist Wiederholung. Nie die Hoffnung aufgeben ;-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jaja, Entprellen ist ja so popeleinfach.

Deshalb ist es für nen Anfänger völlig unzumutbar, erstmal in Tutorials 
oder Codebeispiele reinzuschauen, wie man es richtig machen könnte.

Nur wenn man schon viele mehr schlecht als recht funktionierende 
Entprellungen selber gemacht hat, schaut man da mal rein, hat ein 
Aha-Erlebnis und nie wieder Entprellprobleme.

Aber ich kann keinem verbieten, den steinigen Weg zu gehen, nur zu.


Peter


P.S.:
Schau dochmal ins Assemblerlisting, wieviel Code Du verheizt mit Deinen 
Pointern. Und dann vergleiche mal mit professionellen Entprellroutinen, 
wie schlank und schnell die dagegen sind.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> achja und der Compiler meckert nicht

Bei mir schon (GCC 4.2.4 und GCC 4.3.2), nämlich in der Zeile
if (key_pressed_2(Taster_2))

Da meckert er zurecht folgendes:
warning: passing argument 1 of 'key_pressed_2' makes pointer from integer without a cast

Hast du vielleicht alle Warnungen des Compilers abgeschaltet? Das sollte
man nicht tun.

> und wie kann man diesen Bug beseitigen, bin relativ neu in Sachen C.

Am besten nur key_pressed_1 statt key_pressed_2 verwenden ;-)

Das Problem: Ein Input-Pin des Controllers ist allgemein definiert durch
einen 8-Bit-Port und eine Bitnummer innerhalb dieses Ports. Da der Input
in der Funktion mehrfach abgefragt wird, muss ihr in irgendweiner Form
eine Referenz auf das abzufragende Bit übergeben werden (du übergibst
aktuell nur den Wert des Bits). C kennt aber leider keine
Bitreferenzen, weswegen man sich anders behelfen muss, bspw.

- indem man eine Referenz auf den Port (in Form eines Zeigers) und die
  Bitnummer als zwei Argumente übergibt (so hast du es in
  key_pressed_1 getan),

- indem man die Referenz auf den Port und die Bitnummer in eine Struktur
  packt, und diese dann als eine Einheit übergibt oder

- indem man eine Zugriffsfunktion für den betreffenden Input definiert
  und diese Zugriffsfunktion als Funktionszeiger an die Entprellfunktion
  übergibt.

Da die beiden letztgenannten Alternativen nicht viel zur Lesbarkeit
beitragen, wahrscheinlich den Programmcode vergrößern, einiges an
Verständnis über Strukturen bzw. Funktionszeigern erfordern und neue
potenzielle Fehlerquellen darstellen, würde ich an deiner Stelle einfach
das key_pressed_1 weiterverwenden.

Ganz abgesehen davon taugt deine Entprellroutine nicht sehr viel, da sie
nicht viel mehr tut als mit dem delay_ms die Abfragefrequenz zu
reduzieren. Das bringt zwar schon einen gewissen Verbesserungseffekt,
erschlägt aber bei weitem nicht alle möglichen Fälle. Bspw. sind kurze
Kontaktunterbrechungen bei gedrücktem Taster, wie sie bspw. bei
Kurzhubtastern auftreten können, überhaupt nicht abgedeckt.

Nimm dir Peters Kommentar zu Herzen und schau dir die einschlägigen
Artikel dazu an :)

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.