Guten Tag liebe Forum Mitglieder,
ich bin ein blutiger Anfänger in der Programmierung und suche seit 2
Tagen ein Tutorial oder einen fertigen Code um Tasten bei einem STM32F1
in einer ISR zu entprellen.
Ich weis es gibt jede Menge Code im Forum, doch keiner von denen ich
gefunden habe konnte ich Ansatzweise an dem STM einsetzen (ist mit
großer Wahrscheinlichkeit ein klax, doch leider fällt es mir sehr
schwer).
Mir würde sehr den Code von Peter Dannegger gefallen es einzusetzen,
doch leider verstehe ich diesen Code zu 80% nicht und daher kann ich es
nicht für meinem STM32F1 "umschreiben".
Ich hoffe sehr, dass mir jemand helfen kann.
Ich bedanke mich jetzt schon ganz herzlich im Voraus.
Mit freundlichen Grüßen
Fabian
Hi Fabian,
wenn du den Code nicht verstehst...warum willst du ihn dann benutzen ?
hier ein Schnippsel das vlt. einfacher zu verstehen ist
(und auch funktionieren müsste...blind coded :-)
"PINB"
ist der Port, an dem Du die Tasten anlegst
"KEY0"
ist die Bitnummer einer Taste
"SIGNAL (SIG_OVERFLOW0)"
Ist ein Timerinterrupt von etwa 10ms
Du mußt also nur einen Timerinterrupt und die Pins entsprechend
initialisieren, dann funktioniert der ganze Rest.
Vielen Dank für deine Antwort Uwe!
>> wenn du den Code nicht verstehst...warum willst du ihn dann benutzen ?>
Ja du hast da vollkommen Recht, ich fand den halt nur gut, weil er sehr
Ressourcen schonend ist und viele Funktionen beinhaltet was mich
interessiert. Leider konnte ich es nicht umsetzen.
> SysTick_Config(SystemCoreClock / 1000); // => 1ms Systick
Meine CPU läuft mit 24Mhz , muss ich an der SysTick etwas beachten bzw.
einen Wert ändern um auf die 1ms zu kommen?
Peter Dannegger schrieb:> "PINB"> ist der Port, an dem Du die Tasten anlegst>> "KEY0"> ist die Bitnummer einer Taste>> "SIGNAL (SIG_OVERFLOW0)"> Ist ein Timerinterrupt von etwa 10ms>> Du mußt also nur einen Timerinterrupt und die Pins entsprechend> initialisieren, dann funktioniert der ganze Rest.
Danke Peter!
Ich wage mich erst mal mit dem Code von Uwe und wenn das dann geschafft
ist versuche ich deinen Code umzusetzen.
Grüße
Fabian
Uwe B. schrieb:> hier ein Schnippsel das vlt. einfacher zu verstehen ist> (und auch funktionieren müsste...blind coded :-)
Handelt es sich dabei wirklich um eine Entprellung? Ich glaube nicht...
>Handelt es sich dabei wirklich um eine Entprellung?>Ich glaube nicht...
dann definiere mal "Entprellung"
>weil er sehr>Ressourcen schonend ist
ich glaube beim STM32F1 musst du dir zu begin
keine Gedanken um "Ressourcen" machen :-)
>Meine CPU läuft mit 24Mhz
prüf mal im Debugger den Inhalt der Variabeln "SystemCoreClock"
die muss bei dir "24000000" liefern...dann ist alles ok
in der Clock-Config war noch ein Fehler,
richtig muss es lauten :
Servus Fabian,
Regel 1: für einen Taster benutzt man keinen Interrupt!
Regel 2: Ist die Elektronik in Ordnung? Kannst du das Prellen am
Oszilloskop sehen? Wie viel Zeit dauert das längste gemessene Prellen?
Sind diese Fragen geklärt, dann Regel 3:
Taster werden gepollt, also beispielsweise folgendes:
if (Taster_an_GPIO == HIGH) then counter++;
if ((Taster_an_GPIO == HIGH) && (counter == 10)) then
gewünschte_Routine_ausführen();
Wie hoch der "counter" laufen muss hängt von den gemessenen Paramtern
ab, siehe Oszi!
Noch besser gehts mit nem Timer. Also Timer starten und warten bis der
Tasterzustand sich nicht mehr ändert und dann auf Timerablauf warten.
Grüßle
und du musst den Port und das Bit natürlich anpassen
sorry...hab mich zu sehr an den F4 gewöhnt
>Regel 1: für einen Taster benutzt man keinen Interrupt!
gut...das notier ich mir
Uwe B. schrieb:> shit, beim F1 liegt der GPIOA an "APB2">> also noch eine Korrektur :> RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);>> und du musst den Port und das Bit natürlich anpassen>> sorry...hab mich zu sehr an den F4 gewöhnt>>>Regel 1: für einen Taster benutzt man keinen Interrupt!>> gut...das notier ich mir
Danke diese Einstellungen habe ich schon im Vorfeld gehabt, von daher
kam es auch nicht zu einem Fehler.
Also bei mir ist es nämlich so:
Sobald ich den Taster drücke habe ich am Eingang des Pins einen 3,3V
Pegel.
int main (void)
{
SysTick_Config(SystemCoreClock / 1000); // => 1ms Systick
while(1)
{
loop();
if(button_status==Bit_SET) {
GPIO_SetBits(GPIOB, LED1_TEMPERATUR);
GPIO_ResetBits(GPIOB, LED2_TEMPERATUR);
}
else {
GPIO_SetBits(GPIOB, LED2_TEMPERATUR);
GPIO_ResetBits(GPIOB, LED1_TEMPERATUR);
}
}
}
------------------------------------------------------------------
(stm32f10x_it.c)
extern uint8_t button_status;
void SysTick_Handler(void)
{
static uint32_t ms_cnt=0;
ms_cnt++;
if(ms_cnt>50) {
// 50ms debounce
ms_cnt=0;
button_status=GPIO_ReadInputDataBit(GPIOC,
PIN_VIBRATIONSMOTOR_TASTER);
}
}
---------------------------------------------
Mein Problem ist jetzt, dass die LED2 immer an. Das heisst sobald der
Taster gedrückt ist schaltet die LED1 nicht ein.
Habe ich da was falsch gemacht :(?
>Habe ich da was falsch gemacht
Ja ...sonst würde es ja funktionieren :-)
spass beiseite,
der Fehler liegt event. an meinem Beispiel (war nur so hingeschrieben)
teste erstmal ob der Systick und die Globale Variable "button_status"
funktioniert
1
void SysTick_Handler(void)
2
{
3
static uint32_t ms_cnt=0;
4
5
ms_cnt++;
6
if(ms_cnt>50) {
7
// 50ms debounce
8
ms_cnt=0;
9
button_status=1-button_status; // toggelt den wert
10
}
11
}
die LEDs müssen jetzt mit 20Hz blinken...das müsste ein Flackern sein
und wo ist deine "GPIO init" und was macht die "loop()" ?
Ich habe den Code von Peter vor einiger Zeit mal aufgeteilt und auf
STM32L1 "portiert".
Die Funktion "CollectKeys" soll die zu entprellenden Signale "sammeln"
und muss dementsprechend angepasst werden. Evtl. nötige Invertierungen
können hier oder beim Aufruf in der "Service"-Funktion vorgenommen
werden.
"Service" muss regelmäßig (main-loop, Timer-ISR, usw.) aufgerufen werden
und kümmert sich um die Entprellung an sich.
In der debounce.h können ein paar Einstellungen vorgenommen werden.
Um das Ganze auf anderen Controllern zu nutzen muss nur der Teil
zwischen Zeile 33 und 43 (*.h) erweitert werden.
Michael K. schrieb:>> In der debounce.h können ein paar Einstellungen vorgenommen werden.> Um das Ganze auf anderen Controllern zu nutzen muss nur der Teil> zwischen Zeile 33 und 43 (*.h) erweitert werden.
Vielen Dank Michael!
Auf Zeile 39-40 befindet sich dieses include
#include <avr/io.h>
#include <avr/interrupt.h> // for cli() and sei()
Es ist an sich für einen AVR und ich habe einen STM32F100 kann man es
trotzdem benutzen?
Wenn ja, kann man es wo erhalten??
Liebe Grüße
Fabian
Fabian L. schrieb:> ich habe einen STM32F100
Dann musst du dort einen passenden Abschnitt für diesen Controller
einfügen. Das würde in etwa so aussehen:
1
#elif defined (STM32F1xx)
2
#include<stm32Flxx.h>
3
#define ENABLE_INTERRUPTS __enable_irq
4
#define DISABLE_INTERRUPTS __disable_irq
5
#else
(Das ist ein Beispiel, die genauen Symbole, Headerdateien und Makros
bitte nachsehen!)
Grüße
Stefan