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 :-)
1 | uint8_t button_status=Bit_RESET; |
2 | |
3 | |
4 | //-------------------------------------- |
5 | void gpio_init(void) { |
6 | GPIO_InitTypeDef GPIO_InitStructure; |
7 | |
8 | RCC_AHBPeriphClockCmd(GPIOA, ENABLE); |
9 | |
10 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; |
11 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
12 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; |
13 | GPIO_Init(GPIOA, &GPIO_InitStructure); |
14 | } |
15 | |
16 | |
17 | //-------------------------------------- |
18 | void main(void) { |
19 | |
20 | SysTick_Config(SystemCoreClock / 1000); // => 1ms Systick |
21 | gpio_init(); |
22 | |
23 | while(1) { |
24 | |
25 | if(button_status==Bit_RESET) { |
26 | // mach was |
27 | } |
28 | else { |
29 | // mach was anderes |
30 | } |
31 | } |
32 | } |
33 | |
34 | |
35 | //-------------------------------------- |
36 | void SysTick_Handler(void) |
37 | { |
38 | static uint32_t ms_cnt=0; |
39 | |
40 | ms_cnt++; |
41 | if(ms_cnt>50) { |
42 | // 50ms debounce |
43 | ms_cnt=0; |
44 | button_status=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); |
45 | } |
46 | } |
Gruss Uwe
:
Bearbeitet durch User
"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.
:
Bearbeitet durch User
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 :
1 | RCC_AHBPeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); |
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
shit, beim F1 liegt der GPIOA an "APB2" also noch eine Korrektur :
1 | 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
:
Bearbeitet durch User
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()" ?
:
Bearbeitet durch User
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
Ich wollte mich nochmal bei Uwe bedanke und allen anderen die mir geholfen habe! Es hat jetzt alles geklappt! Liebe Grüße Fabian
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.