Libs for using Nucleo STM32F411 periphery
Introduction
Descruption: This lib uses the hardware peripherie from STM32F411 under serveral conditions. So you can use an quadraturencoder with different timers.
Requirement: Only tested with the nucleo F411. Include the mbed lib! Interfacing details are explained in the documentary of each class.
Overview
- timer modules
- Quadratur Encoder (Version 1.2 - C. Hoyer 12.8.2015)
- SPI modules
- AD5664 (Version 1.1 - C. Hoyer 23.7.2015)
- software modules
- Ringbuffer (Version 0.9 - C. Hoyer 18.8.2015)
- PID-Regler (Version 1.0 - C. Hoyer 17.9.2015)
Diff: TIM/QUADRATURE.h
- Revision:
- 0:1acdcc576936
diff -r 000000000000 -r 1acdcc576936 TIM/QUADRATURE.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TIM/QUADRATURE.h Mon Nov 28 17:27:43 2016 +0000 @@ -0,0 +1,206 @@ +#include "mbed.h" + +#ifndef QUADRATURE_h +#define QUADRATURE_h + +/*! Die Klasse kann aus den Timern 1 bis 5 verschiedene Encoder generieren. Es kann zwischen verschiendenen Encodermodis gewählt werden. Für den STM32 gibt es für die einzelnen Timer verschiedene Kanäle die zu wählen sind: + <CENTER> + <table> + <tr> + <th>Eingang</th> + <th>Timer 1</th> + <th>Timer 2</th> + <th>Timer 3</th> + <th>Timer 4</th> + <th>Timer 5</th> + </tr> + <tr style="text-align: center;"> + <td><strong>CI 1</strong></td> + <td>PA8</td> + <td>PA0</td> + <td>PA6</td> + <td>PB6</td> + <td>PA0</td> + </tr> + <tr style="text-align: center;"> + <td><strong>CI 1</strong></td> + <td>PE9</td> + <td>PA5</td> + <td>PB4</td> + <td>PD12</td> + <td>-</td> + </tr> + <tr style="text-align: center;"> + <td><strong>CI 1</strong></td> + <td>-</td> + <td>PA15</td> + <td>PC6</td> + <td>-</td> + <td>-</td> + </tr> + <tr style="text-align: center;"> + <td><strong>CI 2</strong></td> + <td>PA9</td> + <td>PA1</td> + <td>PB5</td> + <td>PD13</td> + <td>PA1</td> + </tr> + <tr style="text-align: center;"> + <td><strong>CI 2</strong></td> + <td>PE11</td> + <td>PB3</td> + <td>PA7</td> + <td>PB7</td> + <td>-</td> + </tr> + <tr style="text-align: center;"> + <td><strong>CI 2</strong></td> + <td>-</td> + <td>-</td> + <td>PC7</td> + <td>-</td> + <td>-</td> + </tr> +</table> +</CENTER> +<b>Achtung!</b> Es können Doppelbelegungen vorkommen! Bitte vorher prüfen, ob der Pin nicht schon verwendet wird. Zudem kann es passieren das mehrfach der gleiche Timer genutzt wird. Mit einer +Neudeklaration des Timers wird dieser Überschrieben mit den zuletzt verwendeten Parametern. Zudem gibt es einen Interrupt Eventhandler der bei Über- und Unterlauf des Timers eine Timercarry Variable hoch bzw. runter zählt. +So kann man bei Frequenzmessungen den Überlauf mit betrachten. + + * @code + * #include "mbed.h" + * #include "QUADRATURE.h" + * + * int Event_Routine(){ .... } // Irgendeine Funktion die bei Timerüberlauf aufgerufen wird + * + * int main() { + * + * QUADRATURE encoder(1, 3, 'A', 8, 0, 'A', 9, 0); // Instanz mit Timer 1, Modus 3, + * // CI1: Port A, CI1: Pin 8, rising edge + * // CI2: Port A, CI2: Pin 9, rising edge + * + * encoder.setDownRes(); // Setzt die Pull Down Widerstände + * + * encoder.startTIM(); // Startet den Timer + * + * encoder.setIRQ_METHODE(Event_Routine); // Bei Timerüberlauf wird diese Routine aufgerufen + * + * while(1){ + * printf("Value: %i\r\n", encoder.getTIM()); // Ausgabe des aktuellen Timerwerts als Integer + * printf("Carry: %i\r\n", encoder.getCARRY()); // Ausgabe des aktuellen Timerüberlaufs als signed short + * } + * } + * + * @endcode + */ + + class QUADRATURE + { + + public: + /*! Konstruktor zum Erstellen einer Instanz für einen bestimmten Timer und die Input Pins. Nach dem Erstellen der Instanz sollte der Timer nicht für andere + Zwecke verwendet werden. Nach dem Erstellen sind die Encoder voll einsatzbereit und kann mit der "startTIM"-Funktion gestartet werden. */ + /*! + \param tim <b>Entsprechender Timer</b> (Die Funktion wird bei der STM32F-Serie nur von Timer 1-5 unterstützt). + \param mode <b>Encoder Modus</b><br> + - 1: Zählt hoch/runter auf CI2-Flanke unter Bedingung der Spannung an CI1<br> + - 2: Zählt hoch/runter auf CI1-Flanke unter Bedingung der Spannung an CI2<br> + - 3: Zählt hoch/runter auf CI1-Flanke und CI2-Flanke unter Bedinung der Spannung an den jeweiligen anderen Eingang<br> + \param CI1_PORT <b>Capture Input 1 Port</b> Entsprechend den Port z.B. A,B,C,D,E des ausgewählten Eingangs aus der Tabelle entnehmen. + \param CI1_PIN <b>Capture Input 1 Pin</b> Entsprechend den Pin zu dem ausgewählten Eingang aus der Tabelle entnehmen. + \param CI1_POL <b>Capture Input 1 Polarität</b> Invertiert den Eingang CI1. Standartwert = steigende Flanke + \param CI2_PORT <b>Capture Input 2 Port</b> Entsprechend den Port z.B. A,B,C,D,E des ausgewählten Eingangs aus der Tabelle entnehmen. + \param CI2_PIN <b>Capture Input 2 Pin</b> Entsprechend den Pin zu dem ausgewählten Eingang aus der Tabelle entnehmen. + \param CI2_POL <b>Capture Input 2 Polarität</b> Invertiert den Eingang CI2. Standartwert = steigende Flanke + */ + QUADRATURE(int tim, int mode, char _CI1_PORT, int _CI1_PIN, int CI1_POL, char _CI2_PORT, int _CI2_PIN, int CI2_POL); + + + /*! Destruktor der Klasse */ + ~QUADRATURE(){}; + + /*! Startet den Timer und den IRQ Handler. */ + void startTIM(); + + /*! Stoppt den Timer und den IRQ Handler. */ + void stopTIM(); + + /*! Setzt die Pullup Widerstände beider CI Eingänge */ + void setUpRes(); + + /*! Setzt die Pulldown Widerstände beider CI Eingänge */ + void setDownRes(); + + /*! Gibt aktuellen Timerwert als Integer zurück */ + unsigned int getTIM(); + + /*! Gibt aktuellen Über bzw Unterlaufwert als signed short zurück */ + signed short getCARRY(); + + /*! Setzt für den Timer den Prescaler und das Autoload register */ + /*! + \param pre <b>Prescaler</b> Standartwert = (0x0000) + 1. Von 0x0000 bis 0xFFFF möglich + \param arr <b>Auto Reload</b> Bei diesem Wert beginnt der Timer wieder bei 0x0000. Standartwert = 0xFFFF + */ + void setTIM(int pre, int arr); + + /*! Setzt den entsprechenden GPIO auf die Alternative Funktion für den Timer Eingang. */ + /*! + \param port <b>GPIO Port</b> Port der geändert werden soll + \param pin <b>GPIO Pin</b> Pin der geändert werden soll + \param tim <b>Timer</b> Für die Auswahl zwischen den Alternativen Funktionen notwendig + */ + void setGPIO(char port, int pin, int tim); + + + /*! Interrupt Routine bei Überlauf bzw. Unterlauf des Timers. */ + void UPDATE_HANDLER(void); + + /*! Setzt eine weitere Routine die verwendet werden kann, wenn der Timer Interrupthandler aufgerufen wird. */ + /*! + \param IRQ_HANDLER_METHODE Adresse zur weiteren Routine + */ + void setIRQ_METHODE(void (*IRQ_HANDLER_METHODE)(void)); + + protected: + + //! Caputure Input 1 Portname + char CI1_PORT; + //! Caputure Input 2 Portname + char CI2_PORT; + //! Caputure Input 1 Pin + int CI1_PIN; + //! Caputure Input 2 Pin + int CI2_PIN; + //! Pointer zum zuletzt definierten GPIO + GPIO_TypeDef *portpo; + //! Pointer zum aktuell definierten Timer + TIM_TypeDef *tipo; + //! Pointer zum aktuell definierten Interrupt Handler + IRQn_Type temp_ITM; + //! Freigabe zur Verwendung externer Funktionen + bool extfct; + //! Externe Funktion bei Timer Interrupt aufrufen + void (*IRQ_HANDLER_EXTERN)(void); + + //! Timer Über und Unterlauf Zähler (Wenn Unterlauf wird decrementiert, wenn Überlauf wird incrementiert) + signed short TIMERCARRY; + //! Funktion zum Zuweisen der ISR zum Handler der erstellten Instanz + static void _UPDATE_HANDLER(void); + //! Pointer zur Adresse der erstellte Instanz + static QUADRATURE *instance; + + + /*! Wählt das passende GPIO register aus und schreibt es in den Pointer portpo */ + /*! + \param port <b>Portname</b> Welcher Port gewählt werden soll z.B. A,B,... + */ + void GPIOchoose(char port); + + + + +}; + +#endif \ No newline at end of file