Dienstag, 16. September 2014

Debounce / Entprellen für STM32

Hallo Entwickler,

gestern und heute habe ich mir überlegt, wie man mit dem STM32F10x elegant Tasten entprellen kann. Eine gute Einführung zu diesem Thema liefert http://www.emcu.it/STM32/STM32Discovery-Debounce/STM32Discovery-InputWithDebounce_Output_UART_SPI_SysTick.html . Von dort habe ich auch die grundsätzlich Idee zu meiner Lösung. An drei Stellen habe ich jedoch Verbesserungen vorgenommen:

  • Meine Lösung arbeitet mit bis zu 16 Tastern (also einem gesamten Port)
  • Meine Lösung hat nur halb so viel Speicherplatzverbrauch pro Taster
  • Meine Lösung gibt einen Tastimpuls verzögerungsfrei weiter.
Den letzten Punkt muss ich wohl noch ein wenig detaillierter ausführen. Der emcu-Code stellt einen Pegelwechsel an einem Pin fest und beginnt dann, die entsprechende Pegelvariable hochzuzählen. Erst wenn diese Pegelvariable nach mehreren Durchläufen einen bestimmten Wert erreicht hat, wird der Tastendruck bzw. das Loslassen detektiert. Ich gehe da einen anderen Weg: Sobald ein Pegelwechsel erkannt wird, wird dieser sofort weitergegeben. Danach schließt sich eine "Totzeit" an, in der kein weiterer Pegelwechsel erkannt wird. Jegliches Prellen in dieser Zeit wird also sicher unterdrückt.

So langsam werde ich auch vertraut mit bestimmten Möglichkeiten, dem Compiler und dem Linker in meiner Toolchain Anweisungen im Code zu geben. Sehr interessant für den vorliegenden Anwendungsfall ist beispielsweise das "__attribute__((weak))".

Dieses kommt (per define abgekürzt mit "AW") in dem Modul debounce.c zum Einsatz, um überschreibbare Funktionsdefinitionen für die Ereignishandler meiner Debounce-Routine zu realisieren. Das gleiche Prinzip kommt auch bei den Interrupt-Handlern der Standard Peripherial Libary zum Einsatz. Die Idee ist einfach: Die mit weak attributierte Funktion kann durch eine gleichnamige Funktion in einer beliebigen c-Datei überschrieben werden. Ist keine derartige Überschreibung definiert, wird eben die Weak-Standardimplementierung verwendet. Üblicherweise macht die Standardimplementierung einfach garnichts... Schaut Euch einfach die Funktionen DEBOUNCE_click() und DEBOUNCE_up() in debounce.c und main.c an.


Das Beispiel im SVN ist auf das von mir empfohlene 4€-STM32F103-Board zugeschnitten: Eine LED ist an PA1 angeschlossen; der Taster (in meinem Fall einfach eine Steckbrücke) befindet sich an PB0.

Keine Kommentare:

Kommentar veröffentlichen