Bascom Debounce ohen Sprung

tenor

Mitglied
30. Sep. 2012
169
0
16
44
Sprachen
  1. BascomAVR
Hallo!
um mein Menü endlich "sauberer" zu gestalten, benötige ich eine gute Tastenentprellung, so dass ich nicht mehr
auf die debounce routine angewiesen bin.
Nur so kann ich unnötige Sprünge vermeiden und den GOTO Befehl aus meinem Code verbannen.

Am liebsten wäre mir die debounce routine ohne sprung, da hat nich zufällig jemand die sourcen von? :)

Habe auf mikrocontroller.net folgendes für c gefunden:
Code:
/************************************************************************/
/*                                                                      */
/*                      Not so powerful Debouncing Example              */
/*                      No Interrupt needed                             */
/*                                                                      */
/*              Author: Peter Dannegger                                 */
/*                                                                      */
/************************************************************************/
// Target: ATtiny13
 
#include <avr/io.h>
#define F_CPU 9.6e6
#include <util/delay.h>
 
 
#define debounce( port, pin )                                         \
({                                                                    \
  static uint8_t flag = 0;     /* new variable on every macro usage */  \
  uint8_t i = 0;                                                      \
                                                                      \
  if( flag ){                  /* check for key release: */           \
    for(;;){                   /* loop ... */                         \
      if( !(port & 1<<pin) ){  /* ... until key pressed or ... */     \
        i = 0;                 /* 0 = bounce */                       \
        break;                                                        \
      }                                                               \
      _delay_us( 98 );         /* * 256 = 25ms */                     \
      if( --i == 0 ){          /* ... until key >25ms released */     \
        flag = 0;              /* clear press flag */                 \
        i = 0;                 /* 0 = key release debounced */        \
        break;                                                        \
      }                                                               \
    }                                                                 \
  }else{                       /* else check for key press: */        \
    for(;;){                   /* loop ... */                         \
      if( (port & 1<<pin) ){   /* ... until key released or ... */    \
        i = 0;                 /* 0 = bounce */                       \
        break;                                                        \
      }                                                               \
      _delay_us( 98 );         /* * 256 = 25ms */                     \
      if( --i == 0 ){          /* ... until key >25ms pressed */      \
        flag = 1;              /* set press flag */                   \
        i = 1;                 /* 1 = key press debounced */          \
        break;                                                        \
      }                                                               \
    }                                                                 \
  }                                                                   \
  i;                           /* return value of Macro */            \
})
 
/*
   Testapplication
 */
int main(void)
{
  DDRB  &= ~(1<<PB0);
  PORTB |=   1<<PB0;
  DDRB  |=   1<<PB2;
  DDRB  &= ~(1<<PB1);
  PORTB |=   1<<PB1;
  DDRB  |=   1<<PB3;
  for(;;){
    if( debounce( PINB, PB1 ) )
      PORTB ^= 1<<PB2;
    if( debounce( PINB, PB0 ) )
      PORTB ^= 1<<PB3;
  }
}

Wie bekomme ich das am besten nach Bascom?
Mein Versuch scheitert bisher dabei die IF Abfrage entsprechend zu stellen.


Nutzt ihr zu Tastenentprellung auch debounce, oder wie oben selbst geschriebene Routinen?
Bisher habe ich nur pullup Wiederstände verlötet, macht es Sinn einen Kondensator an jedem Schalter anzubringen und Hardware mäßig zu entprellen?
Aktuell ist mir das bei dem Projekt jetzt nicht so recht, aber vielleicht mal beim nächsten.
 
Von der Idee her sollte das so passen. (kann das erst heute Abend kompilieren)
Code:
declare entprellen (byref pin) as byte
local flag as byte
local val as byte

if flag = 1 then
	do
		if pin = 1 then
			entprellen = 0
			exit do
		else
			waitms 25
			flag = 0
			entprellen = 0
			exit do
		end if
	Loop
else if flag = 0 then
	do
		if pin = 0 then
			entprellen = 0
			exit do
		else
			waitms 25
			flag = 1
			entprellen = 1
			exit do
		end if
	loop
end if
return

Aber nochmal die Frage, wie macht ihr das?
Macht ihr das Hardware mäßig mit RC Glied, oder nur Software?
Oder auch mit so einer Routine?

Hier finde ich die Zeit zum entprellen recht lang. Sind ja zusammen 50 ms. die in jedem Fall gewartet werden.
Die Bascom variante warte ja nur 25 ms.

Kennt jemand eine effektiviere Lösung?

EDIT:
Leider lässt sich z.B. Pind.7 diesem pin nicht zuweisen...

so funktionierts, ist aber keine allgemeingültige Funktion, man muß die IF Anweisung immer bearbeiten..
Code:
Function Entprellen(byval Pin As Byte)
Local Flag As Byte
Local Val As Byte

If Flag = 1 Then
   Do
      'if pin = 1 then
      If Pin = 40 Then Val = Pind.0
      If Val = 1 Then
         Entprellen = 0
         Exit Do
      Else
      Waitms 25
         Flag = 0
         Entprellen = 0
         Exit Do
      End If
   Loop
Elseif Flag = 0 Then
    Do
        If Pin = 40 Then Val = Pind.0
        If Val = 0 Then
            Entprellen = 0
            Exit Do
        Else
            Waitms 25
            Flag = 1
            Entprellen = 1
            Exit Do
        End If
    Loop
End If
End Function
Wäre super wenn da einer ne Verbesserung kennt.
 
Hallo,

Aber nochmal die Frage, wie macht ihr das?
Macht ihr das Hardware mäßig mit RC Glied, oder nur Software?
Oder auch mit so einer Routine?

Hier finde ich die Zeit zum entprellen recht lang. Sind ja zusammen 50 ms. die in jedem Fall gewartet werden.
Die Bascom variante warte ja nur 25 ms.

Kennt jemand eine effektiviere Lösung?

50ms warten ist echt uneffektiv :p da kann ich dir nur zustimmen.
Ein wenig könnte man über nen Keramik (22-100nF) parallel zum Taster entprellen. Ich würde aber nicht die Hand dafür ins Feuer legen das es dann wirklich immer sauber ist. :rolleyes:

In Bascom verwende ich normalerweise Debounce. Das ist aber auch nicht so toll effektiv. Es arbeitet auch über eine Wartezeit.

In Assembler habe ich dafür ein 8Bit-Register als Schieberegister verwendet. Sieh mal bei meinem Projekt mit dem Magierstab rein. Dadurch wird der sonstige Ablauf überhaupt nicht ausgebremst. Es gibt keinerlei Wartezeiten.

Gruß
Dino
 
Aber nochmal die Frage, wie macht ihr das?


Hallo!

Eine bessere Möglichkeit als 50ms Wartezeit wäre die Kombination aus WAITMS und BITWAIT.
Ich verwende das persönlch am Meisten, weil ich damit bestimmte Menüwechsel besser steuern kann.
Ein Beispiel so ad hoc:
Code:
Do
If Taster = 0 Then Gosub Taster_isr

Loop

'-------------------------------------
Taster_isr:

Locate 1 , 1
Lcd "Untermenue"

Locate 2 , 1
Lcd "                "

Waitms 10
Bitwait Taster , Set

'---------------------
Locate 2 , 1
Lcd "Eingabe:    "
.
.
.
.
Return
'-------------------------------------


Hin und wieder verwende ich auch einen kleinen Kondensator parallel zum Taster......
Manchmal auf ohne Widerstand, aber das wird nicht gern gesehen. :wink:


Letztlich liegt es aber immer an der Programmierung!
Ein Programm funktioniert nun mal nicht wie ein Baukasten, bei dem man bestimmte Module immer wieder in gleicher Weise verwenden kann.
Das wäre ja zuuuuu schön und auch zu einfach.

Wie du ja selber schon gemerkt hast ist es nicht damit getan ein Programm bedienungs- und ausführungstechnisch richtig zu schreiben.....
sondern auch die Speicherbereiche (Variablen) und die zeitlichlich Abläufe im Auge zu behalten. :cool:


Grüße,
Cassio
 
Hi!
das mit dem Schiebregistern ist ja mal was ganz neues :) Es gibt ja doch schon einige Wege die zum Ziel führen.

Hm, mit bitwait könnte ich meine Funktion auch noch erweitern und so die eine Pause dadurch ersetzen.

Dennoch würde ich gerne eine separate Funktion schreiben die ich aufrufen kann wie die debounce Funktion.
Nur halt ohne Sprung.

Also in etwa so wie sie da steht, aber wie bekomme ich den Taster richtig übergeben?
Den Parameter kann man als bit deklarieren, aber wenn ich dann den Pind.0 z.B. eintrage, dann akzeptiert er es so nicht.
Und will auch das die Variable byval und nicht byref übergeben wird.
Das bringt dann natürlich auch nichts, da sich der Taster Wert ja in der Funktion dann nicht mehr ändern kann!

Die If Anweisung dadrin funktioniert zwar, aber ist ja nun auch keine schöne Lösung.

Das man nicht immer mit fertigen Bausteinen arbeiten kann ist mir klar, dennoch würde ich so eine Funktion sehr oft benötigen ;)
Wenn da noch einer einen Tip hat, wäre das echt Klasse!
 
Hallo,

Dennoch würde ich gerne eine separate Funktion schreiben die ich aufrufen kann wie die debounce Funktion.

denk denn daran das du keinen PC vor dir hast. Das ist ein Mikrocontroller mit begrenztem Speicher und Performance. Mach nicht so viel Gedöns das du aus Hochsprachen kennst. Das verbraucht alles Speicher und Performance. Bei jedem Funktionsaufruf muß er zusätzlich die lokalen Variablen anlegen und auch wieder vernichten. Das kostet alles Performance von der du sowieso nicht so viel hast. Bei embedded Systemen mußt du auf anderen Pfaden wandeln.

Bau dir lieber globale Variablen die du in jeder Subroutine als Schmierzettel verwenden kannst und mach die Werteübergabe auch in globalen Variablen. Das spart zusätzlichen Organisationsaufwand im Programm.

In Assembler benutzt man für sowas entweder Speicheradressen die man extra für solche Aufgaben einplant oder noch besser direkt nicht benutzte Prozessorregister.

Gruß
Dino
 
ok, das mit den globalen Variablen werde ich berücksichtigen ;)

Diese Funktionen nicht zu nutzen, sondern alles ohne zu machen, macht vom Programm aus
Compiler Sicht wahrscheinlich wenig unterschied, aber die Lesbarkeit im Code wird dadurch erheblich gesteigert,
ausserdem wird es natürlich auch einfacher nicht jede grundlegende Funktion erneut machen zu müssen.

Ich muss mich halt durch mein Menü hangeln, da brauch ich eine debounce alternative, nur halt ohne Sprung..
Manchmal macht das halt mehr Sinn.
Ob man jetzt eine selbstgeschriebene oder eine Bascom Funktion benutzt, ist wahrscheinlich nicht so grundlegend anders.

Währe halt noch schön wenn man den Pin übergeben könnte.
In der C Funktion shiften die ja den Port in das Register, hab aber noch keine Bascom alternative gefunden
die mir hier weiterhilft.
 
Hi,

Diese Funktionen nicht zu nutzen, sondern alles ohne zu machen, macht vom Programm aus
Compiler Sicht wahrscheinlich wenig unterschied
,
das glaube ich nicht. Wenn du einen optimierenden Compiler (wie C) hättest würde ich dir zustimmen. Bascom ist aber kein optimierender Compiler. Irgendwie kommt es mir vor als wenn man mit jedem Befehl einfach einen Codeblock reinsetzt. Du mußt also selber optimieren. Dafür mußt du aber auch bedenken was dabei unter der Motorhaube abläuft.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)