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)

TIM/QUADRATURE.h

Committer:
ChrisselH
Date:
2016-11-28
Revision:
0:1acdcc576936

File content as of revision 0:1acdcc576936:

#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