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)
Revision:
0:1acdcc576936
--- /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