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

  1. timer modules
    1. Quadratur Encoder (Version 1.2 - C. Hoyer 12.8.2015)
  2. SPI modules
    1. AD5664 (Version 1.1 - C. Hoyer 23.7.2015)
  3. software modules
    1. Ringbuffer (Version 0.9 - C. Hoyer 18.8.2015)
    2. PID-Regler (Version 1.0 - C. Hoyer 17.9.2015)
Committer:
ChrisselH
Date:
Mon Nov 28 17:27:43 2016 +0000
Revision:
0:1acdcc576936
port from priv lib

Who changed what in which revision?

UserRevisionLine numberNew 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