Wer einen (oder mehrere) Drehgeber (Rotary Encoder) an den STM32F4 anschließen will, kann diese Library(s) benutzen.
Zum Messen der Signale werden zwei Kanäle von einem Timer benötigt. Ich habe die Librarys wieder für “TIM2, TIM3, TIM4, TIM5″ geschrieben.
Die zwei Port-Pins die benutzt werden sollen, müssen im C-File eingestellt werden.
Bei der Initialisierung muss der Mode, die Drehrichtung und die Auflösung vom Counter eingestellt werden.
Der Mode bestimmt bei welcher Flanke (A,B oder A+B) der Counter getriggert wird, und die Auflösung bestimmt ab welchem Wert der Counterüberlauf stattfindet.
In der Software sind die Pull-Ups der Eingänge aktiviert, der Drehgeber muss also gegen GND schalten.
Bild :
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : GPIO, TIM Benutzte Librarys : keine |
Enumerationen (für Encoder mit TIM2) :
1 2 3 4 5 | typedef enum { ENC_T2_MODE_2A = 0, // Counter Zählt bei jeder Flanke von Eingang_A ENC_T2_MODE_2B = 1, // Counter Zählt bei jeder Flanke von Eingang_B ENC_T2_MODE_4AB = 2 // Counter Zählt bei jeder Flanke von Eingang_A UND Eingang_B }ENC_TIM2_MODE_t; |
:
1 2 3 4 | typedef enum { ENC_T2_TYP_NORMAL = 0, // Counter incrementiert bei rechts ENC_T2_TYP_REVERS = 1 // Counter decrementiert bei rechts }ENC_TIM2_TYP_t; |
Funktionen (für Encoder mit TIM2) :
1 2 | void UB_ENCODER_TIM2_Init(ENC_TIM2_MODE_t mode, ENC_TIM2_TYP_t typ, uint16_t maxwert); // zum init vom Encoder uint16_t UB_ENCODER_TIM2_ReadPos(void); // zum auslesen vom Counterwert |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | //-------------------------------------------------------------- // File : main.c // Datum : 23.07.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.0 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der Encoder Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_led.h" #include "stm32_ub_encoder_tim2.h" int main(void) { uint16_t counterwert; SystemInit(); // Quarz Einstellungen aktivieren // init aller LEDs UB_Led_Init(); // init vom Drehgeber (Rotary-Encoder) per Timer2 // Mode = normal, Werte [0...15] UB_ENCODER_TIM2_Init(ENC_T2_MODE_2A, ENC_T2_TYP_NORMAL, 0x000F); while(1) { // Drehgeber auslesen counterwert=UB_ENCODER_TIM2_ReadPos(); // die 4 LEDs je nach Counterwert ein- /ausschalten if((counterwert&0x01)==0) UB_Led_Off(LED_GREEN); else UB_Led_On(LED_GREEN); if((counterwert&0x02)==0) UB_Led_Off(LED_BLUE); else UB_Led_On(LED_BLUE); if((counterwert&0x04)==0) UB_Led_Off(LED_RED); else UB_Led_On(LED_RED); if((counterwert&0x08)==0) UB_Led_Off(LED_ORANGE); else UB_Led_On(LED_ORANGE); } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Danke für den nützlichen Beispielcode!
Mein Encoder an den Pins PD12 und PD13 funktioniert mit deiner Bibliothek wunderbar (mit TIM4).
Jetzt versuche ich, den Encoder an den Input-Pins A: PB14 und B: PB15 zu betreiben. Ich wollte TIM8_CH2N TIM8_CH2N verwenden (auf ABP2 statt ABP1), leider bisher ohne Erfolg: ich lese immer nur 0.
Für Hinweise oder ein funktionierendes Beispiel wäre ich also dankbar!
Ich hab inzwischen noch das Datenblatt besser gelesen und gesehen, dass das wohl mit diesen beiden Pins nicht geht. Laut 14.3.16 “Encoder interface mode” werden zwingend die Inputs TI1 und TI2 vorausgesetzt, und die lassen sich nicht mit CH2N und CH3N verbinden. Ich werde also andere Pins verwenden müssen…
Muss es immer CH1 und CH2 sein? Bei Timer2/5 finde ich auf dem STM32F429 Board keine freien Ports dafür.
Ja, es muss CH1 und CH2 sein. Timer3 PB4, PA7 sind frei.
Mist, ich brauche aber 32Bit
dann ließ den counterwert zyklisch mit einem Timer aus und benutz eine 32bit Hilfsvariable…wo ist das Problem.
Hab gerne “saubere” Lösungen . Hab es jetzt aber zum laufen bekommen. Am Decoder fehlten die Widerstände. Komisch das es am STM32F407 auch ohne lief.
Aber danke für deine Hilfe. Mit der Hilfsvariable behalte ich mal für andere Sachen im Kopf .
Schönen Sonntag noch…..
Gibt es einen Interrupt der auslöst wenn sich der Zählerstand vom Counter verändert?
ich glaube nicht…da wirst du einen externen Interrupt benutzen müssen
oder per Timer den Wert pollen und auf Veränderung abprüfen.
Ich verstehe noch nicht wo genau festgelegt / ausgewählt wird welche Pins ich z.B. im CooCox Example mit TIM2 verwendet werden. Kann mir das jemand verraten an welche Pins ich A und B anschließen muss?
im C-File ganz oben unter “Definition der zwei Rotary-Encoder Pins”
die Pins sind nicht beliebig, sondern hängen vom Timer ab.
Im Beispiel wird TIM2 und die Pins : PA0, PA1 benutzt
hallo
Ich habe es nicht bekommen, um auf meinem stm32f429 arbeiten
Jeder kann die Teile des Codes mit Timer3 und PB4 setzen, PA7 konfiguriert?.
Ich bin hier, um den Arm
Das testo Ich habe mit Google übersetzt.
Verzeihen Sie, ich habe keine Ahnung von deutscher
please write your question in english again.
Hi,
ich versuche GPIO”E” Pin 5 und 6 mittels TIM9 Ch1 und Ch2 zum laufen zu bringen, aber dies funktioniert nicht. Ich habe alle Timer und pins,…. angepasst an TIM 9 und GPIO E, aber ich bekomme immer nur Position “0″ ausgelesen.
Ich benutze das STM32E407 Board.
Die anderen Timer von dir funktionieren ohne Probleme.
Hat es mit TIM9 etwas besonderes auf sich, da es ein “high” speed timer ist?
Kannst du mir bitte weiterhelfen.
Danke und viele Grüße
Flo
Der Encoder-Mode funktioniert nur beim Timer-1,8,2,3,4,5.
Sorry for my english. Please Teach how to make an interrupt encoder included, and did not work in the main loop? Thank you.
you dont need an interrupt for the rotary encoder.
you can read the actual counter value at any time you want.