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)
TIM/QUADRATURE.h@0:1acdcc576936, 2016-11-28 (annotated)
- Committer:
- ChrisselH
- Date:
- Mon Nov 28 17:27:43 2016 +0000
- Revision:
- 0:1acdcc576936
port from priv lib
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ChrisselH | 0:1acdcc576936 | 1 | #include "mbed.h" |
ChrisselH | 0:1acdcc576936 | 2 | |
ChrisselH | 0:1acdcc576936 | 3 | #ifndef QUADRATURE_h |
ChrisselH | 0:1acdcc576936 | 4 | #define QUADRATURE_h |
ChrisselH | 0:1acdcc576936 | 5 | |
ChrisselH | 0:1acdcc576936 | 6 | /*! 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: |
ChrisselH | 0:1acdcc576936 | 7 | <CENTER> |
ChrisselH | 0:1acdcc576936 | 8 | <table> |
ChrisselH | 0:1acdcc576936 | 9 | <tr> |
ChrisselH | 0:1acdcc576936 | 10 | <th>Eingang</th> |
ChrisselH | 0:1acdcc576936 | 11 | <th>Timer 1</th> |
ChrisselH | 0:1acdcc576936 | 12 | <th>Timer 2</th> |
ChrisselH | 0:1acdcc576936 | 13 | <th>Timer 3</th> |
ChrisselH | 0:1acdcc576936 | 14 | <th>Timer 4</th> |
ChrisselH | 0:1acdcc576936 | 15 | <th>Timer 5</th> |
ChrisselH | 0:1acdcc576936 | 16 | </tr> |
ChrisselH | 0:1acdcc576936 | 17 | <tr style="text-align: center;"> |
ChrisselH | 0:1acdcc576936 | 18 | <td><strong>CI 1</strong></td> |
ChrisselH | 0:1acdcc576936 | 19 | <td>PA8</td> |
ChrisselH | 0:1acdcc576936 | 20 | <td>PA0</td> |
ChrisselH | 0:1acdcc576936 | 21 | <td>PA6</td> |
ChrisselH | 0:1acdcc576936 | 22 | <td>PB6</td> |
ChrisselH | 0:1acdcc576936 | 23 | <td>PA0</td> |
ChrisselH | 0:1acdcc576936 | 24 | </tr> |
ChrisselH | 0:1acdcc576936 | 25 | <tr style="text-align: center;"> |
ChrisselH | 0:1acdcc576936 | 26 | <td><strong>CI 1</strong></td> |
ChrisselH | 0:1acdcc576936 | 27 | <td>PE9</td> |
ChrisselH | 0:1acdcc576936 | 28 | <td>PA5</td> |
ChrisselH | 0:1acdcc576936 | 29 | <td>PB4</td> |
ChrisselH | 0:1acdcc576936 | 30 | <td>PD12</td> |
ChrisselH | 0:1acdcc576936 | 31 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 32 | </tr> |
ChrisselH | 0:1acdcc576936 | 33 | <tr style="text-align: center;"> |
ChrisselH | 0:1acdcc576936 | 34 | <td><strong>CI 1</strong></td> |
ChrisselH | 0:1acdcc576936 | 35 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 36 | <td>PA15</td> |
ChrisselH | 0:1acdcc576936 | 37 | <td>PC6</td> |
ChrisselH | 0:1acdcc576936 | 38 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 39 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 40 | </tr> |
ChrisselH | 0:1acdcc576936 | 41 | <tr style="text-align: center;"> |
ChrisselH | 0:1acdcc576936 | 42 | <td><strong>CI 2</strong></td> |
ChrisselH | 0:1acdcc576936 | 43 | <td>PA9</td> |
ChrisselH | 0:1acdcc576936 | 44 | <td>PA1</td> |
ChrisselH | 0:1acdcc576936 | 45 | <td>PB5</td> |
ChrisselH | 0:1acdcc576936 | 46 | <td>PD13</td> |
ChrisselH | 0:1acdcc576936 | 47 | <td>PA1</td> |
ChrisselH | 0:1acdcc576936 | 48 | </tr> |
ChrisselH | 0:1acdcc576936 | 49 | <tr style="text-align: center;"> |
ChrisselH | 0:1acdcc576936 | 50 | <td><strong>CI 2</strong></td> |
ChrisselH | 0:1acdcc576936 | 51 | <td>PE11</td> |
ChrisselH | 0:1acdcc576936 | 52 | <td>PB3</td> |
ChrisselH | 0:1acdcc576936 | 53 | <td>PA7</td> |
ChrisselH | 0:1acdcc576936 | 54 | <td>PB7</td> |
ChrisselH | 0:1acdcc576936 | 55 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 56 | </tr> |
ChrisselH | 0:1acdcc576936 | 57 | <tr style="text-align: center;"> |
ChrisselH | 0:1acdcc576936 | 58 | <td><strong>CI 2</strong></td> |
ChrisselH | 0:1acdcc576936 | 59 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 60 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 61 | <td>PC7</td> |
ChrisselH | 0:1acdcc576936 | 62 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 63 | <td>-</td> |
ChrisselH | 0:1acdcc576936 | 64 | </tr> |
ChrisselH | 0:1acdcc576936 | 65 | </table> |
ChrisselH | 0:1acdcc576936 | 66 | </CENTER> |
ChrisselH | 0:1acdcc576936 | 67 | <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 |
ChrisselH | 0:1acdcc576936 | 68 | 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. |
ChrisselH | 0:1acdcc576936 | 69 | So kann man bei Frequenzmessungen den Überlauf mit betrachten. |
ChrisselH | 0:1acdcc576936 | 70 | |
ChrisselH | 0:1acdcc576936 | 71 | * @code |
ChrisselH | 0:1acdcc576936 | 72 | * #include "mbed.h" |
ChrisselH | 0:1acdcc576936 | 73 | * #include "QUADRATURE.h" |
ChrisselH | 0:1acdcc576936 | 74 | * |
ChrisselH | 0:1acdcc576936 | 75 | * int Event_Routine(){ .... } // Irgendeine Funktion die bei Timerüberlauf aufgerufen wird |
ChrisselH | 0:1acdcc576936 | 76 | * |
ChrisselH | 0:1acdcc576936 | 77 | * int main() { |
ChrisselH | 0:1acdcc576936 | 78 | * |
ChrisselH | 0:1acdcc576936 | 79 | * QUADRATURE encoder(1, 3, 'A', 8, 0, 'A', 9, 0); // Instanz mit Timer 1, Modus 3, |
ChrisselH | 0:1acdcc576936 | 80 | * // CI1: Port A, CI1: Pin 8, rising edge |
ChrisselH | 0:1acdcc576936 | 81 | * // CI2: Port A, CI2: Pin 9, rising edge |
ChrisselH | 0:1acdcc576936 | 82 | * |
ChrisselH | 0:1acdcc576936 | 83 | * encoder.setDownRes(); // Setzt die Pull Down Widerstände |
ChrisselH | 0:1acdcc576936 | 84 | * |
ChrisselH | 0:1acdcc576936 | 85 | * encoder.startTIM(); // Startet den Timer |
ChrisselH | 0:1acdcc576936 | 86 | * |
ChrisselH | 0:1acdcc576936 | 87 | * encoder.setIRQ_METHODE(Event_Routine); // Bei Timerüberlauf wird diese Routine aufgerufen |
ChrisselH | 0:1acdcc576936 | 88 | * |
ChrisselH | 0:1acdcc576936 | 89 | * while(1){ |
ChrisselH | 0:1acdcc576936 | 90 | * printf("Value: %i\r\n", encoder.getTIM()); // Ausgabe des aktuellen Timerwerts als Integer |
ChrisselH | 0:1acdcc576936 | 91 | * printf("Carry: %i\r\n", encoder.getCARRY()); // Ausgabe des aktuellen Timerüberlaufs als signed short |
ChrisselH | 0:1acdcc576936 | 92 | * } |
ChrisselH | 0:1acdcc576936 | 93 | * } |
ChrisselH | 0:1acdcc576936 | 94 | * |
ChrisselH | 0:1acdcc576936 | 95 | * @endcode |
ChrisselH | 0:1acdcc576936 | 96 | */ |
ChrisselH | 0:1acdcc576936 | 97 | |
ChrisselH | 0:1acdcc576936 | 98 | class QUADRATURE |
ChrisselH | 0:1acdcc576936 | 99 | { |
ChrisselH | 0:1acdcc576936 | 100 | |
ChrisselH | 0:1acdcc576936 | 101 | public: |
ChrisselH | 0:1acdcc576936 | 102 | /*! 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 |
ChrisselH | 0:1acdcc576936 | 103 | Zwecke verwendet werden. Nach dem Erstellen sind die Encoder voll einsatzbereit und kann mit der "startTIM"-Funktion gestartet werden. */ |
ChrisselH | 0:1acdcc576936 | 104 | /*! |
ChrisselH | 0:1acdcc576936 | 105 | \param tim <b>Entsprechender Timer</b> (Die Funktion wird bei der STM32F-Serie nur von Timer 1-5 unterstützt). |
ChrisselH | 0:1acdcc576936 | 106 | \param mode <b>Encoder Modus</b><br> |
ChrisselH | 0:1acdcc576936 | 107 | - 1: Zählt hoch/runter auf CI2-Flanke unter Bedingung der Spannung an CI1<br> |
ChrisselH | 0:1acdcc576936 | 108 | - 2: Zählt hoch/runter auf CI1-Flanke unter Bedingung der Spannung an CI2<br> |
ChrisselH | 0:1acdcc576936 | 109 | - 3: Zählt hoch/runter auf CI1-Flanke und CI2-Flanke unter Bedinung der Spannung an den jeweiligen anderen Eingang<br> |
ChrisselH | 0:1acdcc576936 | 110 | \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. |
ChrisselH | 0:1acdcc576936 | 111 | \param CI1_PIN <b>Capture Input 1 Pin</b> Entsprechend den Pin zu dem ausgewählten Eingang aus der Tabelle entnehmen. |
ChrisselH | 0:1acdcc576936 | 112 | \param CI1_POL <b>Capture Input 1 Polarität</b> Invertiert den Eingang CI1. Standartwert = steigende Flanke |
ChrisselH | 0:1acdcc576936 | 113 | \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. |
ChrisselH | 0:1acdcc576936 | 114 | \param CI2_PIN <b>Capture Input 2 Pin</b> Entsprechend den Pin zu dem ausgewählten Eingang aus der Tabelle entnehmen. |
ChrisselH | 0:1acdcc576936 | 115 | \param CI2_POL <b>Capture Input 2 Polarität</b> Invertiert den Eingang CI2. Standartwert = steigende Flanke |
ChrisselH | 0:1acdcc576936 | 116 | */ |
ChrisselH | 0:1acdcc576936 | 117 | QUADRATURE(int tim, int mode, char _CI1_PORT, int _CI1_PIN, int CI1_POL, char _CI2_PORT, int _CI2_PIN, int CI2_POL); |
ChrisselH | 0:1acdcc576936 | 118 | |
ChrisselH | 0:1acdcc576936 | 119 | |
ChrisselH | 0:1acdcc576936 | 120 | /*! Destruktor der Klasse */ |
ChrisselH | 0:1acdcc576936 | 121 | ~QUADRATURE(){}; |
ChrisselH | 0:1acdcc576936 | 122 | |
ChrisselH | 0:1acdcc576936 | 123 | /*! Startet den Timer und den IRQ Handler. */ |
ChrisselH | 0:1acdcc576936 | 124 | void startTIM(); |
ChrisselH | 0:1acdcc576936 | 125 | |
ChrisselH | 0:1acdcc576936 | 126 | /*! Stoppt den Timer und den IRQ Handler. */ |
ChrisselH | 0:1acdcc576936 | 127 | void stopTIM(); |
ChrisselH | 0:1acdcc576936 | 128 | |
ChrisselH | 0:1acdcc576936 | 129 | /*! Setzt die Pullup Widerstände beider CI Eingänge */ |
ChrisselH | 0:1acdcc576936 | 130 | void setUpRes(); |
ChrisselH | 0:1acdcc576936 | 131 | |
ChrisselH | 0:1acdcc576936 | 132 | /*! Setzt die Pulldown Widerstände beider CI Eingänge */ |
ChrisselH | 0:1acdcc576936 | 133 | void setDownRes(); |
ChrisselH | 0:1acdcc576936 | 134 | |
ChrisselH | 0:1acdcc576936 | 135 | /*! Gibt aktuellen Timerwert als Integer zurück */ |
ChrisselH | 0:1acdcc576936 | 136 | unsigned int getTIM(); |
ChrisselH | 0:1acdcc576936 | 137 | |
ChrisselH | 0:1acdcc576936 | 138 | /*! Gibt aktuellen Über bzw Unterlaufwert als signed short zurück */ |
ChrisselH | 0:1acdcc576936 | 139 | signed short getCARRY(); |
ChrisselH | 0:1acdcc576936 | 140 | |
ChrisselH | 0:1acdcc576936 | 141 | /*! Setzt für den Timer den Prescaler und das Autoload register */ |
ChrisselH | 0:1acdcc576936 | 142 | /*! |
ChrisselH | 0:1acdcc576936 | 143 | \param pre <b>Prescaler</b> Standartwert = (0x0000) + 1. Von 0x0000 bis 0xFFFF möglich |
ChrisselH | 0:1acdcc576936 | 144 | \param arr <b>Auto Reload</b> Bei diesem Wert beginnt der Timer wieder bei 0x0000. Standartwert = 0xFFFF |
ChrisselH | 0:1acdcc576936 | 145 | */ |
ChrisselH | 0:1acdcc576936 | 146 | void setTIM(int pre, int arr); |
ChrisselH | 0:1acdcc576936 | 147 | |
ChrisselH | 0:1acdcc576936 | 148 | /*! Setzt den entsprechenden GPIO auf die Alternative Funktion für den Timer Eingang. */ |
ChrisselH | 0:1acdcc576936 | 149 | /*! |
ChrisselH | 0:1acdcc576936 | 150 | \param port <b>GPIO Port</b> Port der geändert werden soll |
ChrisselH | 0:1acdcc576936 | 151 | \param pin <b>GPIO Pin</b> Pin der geändert werden soll |
ChrisselH | 0:1acdcc576936 | 152 | \param tim <b>Timer</b> Für die Auswahl zwischen den Alternativen Funktionen notwendig |
ChrisselH | 0:1acdcc576936 | 153 | */ |
ChrisselH | 0:1acdcc576936 | 154 | void setGPIO(char port, int pin, int tim); |
ChrisselH | 0:1acdcc576936 | 155 | |
ChrisselH | 0:1acdcc576936 | 156 | |
ChrisselH | 0:1acdcc576936 | 157 | /*! Interrupt Routine bei Überlauf bzw. Unterlauf des Timers. */ |
ChrisselH | 0:1acdcc576936 | 158 | void UPDATE_HANDLER(void); |
ChrisselH | 0:1acdcc576936 | 159 | |
ChrisselH | 0:1acdcc576936 | 160 | /*! Setzt eine weitere Routine die verwendet werden kann, wenn der Timer Interrupthandler aufgerufen wird. */ |
ChrisselH | 0:1acdcc576936 | 161 | /*! |
ChrisselH | 0:1acdcc576936 | 162 | \param IRQ_HANDLER_METHODE Adresse zur weiteren Routine |
ChrisselH | 0:1acdcc576936 | 163 | */ |
ChrisselH | 0:1acdcc576936 | 164 | void setIRQ_METHODE(void (*IRQ_HANDLER_METHODE)(void)); |
ChrisselH | 0:1acdcc576936 | 165 | |
ChrisselH | 0:1acdcc576936 | 166 | protected: |
ChrisselH | 0:1acdcc576936 | 167 | |
ChrisselH | 0:1acdcc576936 | 168 | //! Caputure Input 1 Portname |
ChrisselH | 0:1acdcc576936 | 169 | char CI1_PORT; |
ChrisselH | 0:1acdcc576936 | 170 | //! Caputure Input 2 Portname |
ChrisselH | 0:1acdcc576936 | 171 | char CI2_PORT; |
ChrisselH | 0:1acdcc576936 | 172 | //! Caputure Input 1 Pin |
ChrisselH | 0:1acdcc576936 | 173 | int CI1_PIN; |
ChrisselH | 0:1acdcc576936 | 174 | //! Caputure Input 2 Pin |
ChrisselH | 0:1acdcc576936 | 175 | int CI2_PIN; |
ChrisselH | 0:1acdcc576936 | 176 | //! Pointer zum zuletzt definierten GPIO |
ChrisselH | 0:1acdcc576936 | 177 | GPIO_TypeDef *portpo; |
ChrisselH | 0:1acdcc576936 | 178 | //! Pointer zum aktuell definierten Timer |
ChrisselH | 0:1acdcc576936 | 179 | TIM_TypeDef *tipo; |
ChrisselH | 0:1acdcc576936 | 180 | //! Pointer zum aktuell definierten Interrupt Handler |
ChrisselH | 0:1acdcc576936 | 181 | IRQn_Type temp_ITM; |
ChrisselH | 0:1acdcc576936 | 182 | //! Freigabe zur Verwendung externer Funktionen |
ChrisselH | 0:1acdcc576936 | 183 | bool extfct; |
ChrisselH | 0:1acdcc576936 | 184 | //! Externe Funktion bei Timer Interrupt aufrufen |
ChrisselH | 0:1acdcc576936 | 185 | void (*IRQ_HANDLER_EXTERN)(void); |
ChrisselH | 0:1acdcc576936 | 186 | |
ChrisselH | 0:1acdcc576936 | 187 | //! Timer Über und Unterlauf Zähler (Wenn Unterlauf wird decrementiert, wenn Überlauf wird incrementiert) |
ChrisselH | 0:1acdcc576936 | 188 | signed short TIMERCARRY; |
ChrisselH | 0:1acdcc576936 | 189 | //! Funktion zum Zuweisen der ISR zum Handler der erstellten Instanz |
ChrisselH | 0:1acdcc576936 | 190 | static void _UPDATE_HANDLER(void); |
ChrisselH | 0:1acdcc576936 | 191 | //! Pointer zur Adresse der erstellte Instanz |
ChrisselH | 0:1acdcc576936 | 192 | static QUADRATURE *instance; |
ChrisselH | 0:1acdcc576936 | 193 | |
ChrisselH | 0:1acdcc576936 | 194 | |
ChrisselH | 0:1acdcc576936 | 195 | /*! Wählt das passende GPIO register aus und schreibt es in den Pointer portpo */ |
ChrisselH | 0:1acdcc576936 | 196 | /*! |
ChrisselH | 0:1acdcc576936 | 197 | \param port <b>Portname</b> Welcher Port gewählt werden soll z.B. A,B,... |
ChrisselH | 0:1acdcc576936 | 198 | */ |
ChrisselH | 0:1acdcc576936 | 199 | void GPIOchoose(char port); |
ChrisselH | 0:1acdcc576936 | 200 | |
ChrisselH | 0:1acdcc576936 | 201 | |
ChrisselH | 0:1acdcc576936 | 202 | |
ChrisselH | 0:1acdcc576936 | 203 | |
ChrisselH | 0:1acdcc576936 | 204 | }; |
ChrisselH | 0:1acdcc576936 | 205 | |
ChrisselH | 0:1acdcc576936 | 206 | #endif |