Libs for using Nucleo STM32F411 periphery

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers QUADRATURE.cpp Source File

QUADRATURE.cpp

00001 #include "mbed.h"
00002 #include "QUADRATURE.h"
00003 #include "cmsis_nvic.h"
00004 
00005 //====================================================================================================================================
00006 //                                   Initialisieren und mappen der Kanäle, Timer etc
00007 //====================================================================================================================================
00008 QUADRATURE  *QUADRATURE::instance;                                                       // Pointer zur Adresse der Instanz
00009 
00010 
00011 QUADRATURE::QUADRATURE (int tim, int mode, char _CI1_PORT, int _CI1_PIN, int CI1_POL,  char _CI2_PORT, int _CI2_PIN, int CI2_POL): CI1_PORT(_CI1_PORT), CI1_PIN(_CI1_PIN), CI2_PORT(_CI2_PORT), CI2_PIN(_CI2_PIN)
00012 {   
00013   
00014     TIMERCARRY = 0;                                                                     // bei neuem Objekt den entsprechenden Timercarry auf 0 setzen
00015     instance = this;                                                                    // Instanz zuweisung zum neu generierten Objekt
00016     extfct = false;                                                                     // Externe Funktion bei Timer Interrupt deaktiviert
00017 
00018     //Konfiguration des Timers
00019        switch(tim){                                                                     // Konfiguration jedes einzelnen Timers, durch Auswahl    
00020                     case 1:                                                             // TIM1
00021                         RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;                             // Timer 1 aktivieren
00022                         tipo = TIM1;                                                    // Pointer auf Timer1 zuweisen
00023                         temp_ITM = TIM1_UP_TIM10_IRQn;                                  // NVIC Nummer für den Updateinterrupt Timer 1
00024                         NVIC->ISER[0] &= ~(1 << TIM1_UP_TIM10_IRQn);                    // Interrupt Handler für den Timer 1 aktivieren
00025                     break;
00026                     
00027                     case 2:                                                             // TIM2
00028                         RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;                             // Timer 2 aktivieren
00029                         tipo = TIM2;                                                    // Pointer auf Timer2 zuweisen
00030                         temp_ITM =  TIM2_IRQn;                                          // NVIC Nummer für den Updateinterrupt Timer 2
00031                         NVIC->ISER[0] &= ~(1 << TIM2_IRQn);                             // Interrupt Handler für den Timer 2 aktivieren
00032                     break;
00033                     
00034                     case 3:                                                             // TIM3
00035                         RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;                             // Timer 3 aktivieren
00036                         tipo = TIM3;                                                    // Pointer auf Timer3 zuweisen
00037                         temp_ITM =  TIM3_IRQn;                                          // NVIC Nummer für den Updateinterrupt Timer 3
00038                         NVIC->ISER[0] &= ~(1 << TIM3_IRQn);                             // Interrupt Handler für den Timer 3 aktivieren
00039                     break;   
00040 
00041                     case 4:                                                             // TIM4
00042                         RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;                             // Timer 4 aktivieren 
00043                         tipo = TIM4;                                                    // Pointer auf Timer4 zuweisen
00044                         temp_ITM =  TIM4_IRQn;                                          // NVIC Nummer für den Updateinterrupt Timer 4
00045                         NVIC->ISER[0] &= ~(1 << TIM4_IRQn);                             // Interrupt Handler für den Timer 4 aktivieren                        
00046                     break;                
00047 
00048                     case 5:                                                             // TIM5
00049                         RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;                             // Timer 5 aktivieren 
00050                         tipo = TIM5;                                                    // Pointer auf Timer5 zuweisen
00051                         temp_ITM =  TIM5_IRQn;                                          // NVIC Nummer für den Updateinterrupt Timer 5
00052                         NVIC->ISER[1] &= ~(1 << (TIM5_IRQn-31));                        // Interrupt Handler für den Timer 5 aktivieren
00053                     break;
00054                     
00055                     default:                                                            // keinen Timer ausgewählt und Fehlermeldung
00056                         printf("\n \n \r \n  Falscher Timer ausgewahlt! \n \n \r");
00057                         return;
00058                 }   
00059                 
00060         tipo->SMCR  = mode;                                                             // Schreibt den aktuellen Modus in das SMCR Register (Slave Mode)
00061         tipo->CCMR1 = 0xF1F1;                                                           // Mappen der Capture Inputs 1 und 2 auf Timer Input 1 und 2
00062         tipo->CCMR2 = 0x0000;                                                           // Kein mappen der Capture Inputs 3 und 4
00063         tipo->CCER  = 0x0011;                                                           // Capture Inputs 1 und 2 aktivieren 
00064             
00065         // Konfiguration der Pins      
00066         setGPIO (CI1_PORT, CI1_PIN, tim);                                                // Setzt den Port Pin für CI1        
00067         setGPIO (CI2_PORT, CI2_PIN, tim);                                                // Setzt den Port Pin für CI2
00068         
00069         // Konfiguration der Polarität 
00070         if(CI1_POL ==  1){                                                              // Polarität für CI1 ändern auf fallende Flanke 
00071                  tipo->CCER |= 0x0002;                                                   
00072             } 
00073         if(CI2_POL ==  1){                                                              // Polarität für CI2 ändern auf fallende Flanke 
00074                  tipo->CCER |= 0x0020;                                                   
00075             } 
00076             
00077         // Konfiguration der Interrupt Routine
00078         NVIC_SetVector(temp_ITM, (uint32_t) &_UPDATE_HANDLER);                          // Adresse zum IRQ Handler des entsprechenden Timers
00079         NVIC_SetPriority(temp_ITM, 0);                                                  // Festlegen der Priorität (Höchste, damit das nächste Increment mit gezählt wird)
00080         tipo->DIER |= 0x0001;                                                           // Update Interrupt Einstellung im Timer aktivieren
00081         
00082                                                                          
00083     }
00084 
00085 
00086 
00087 void QUADRATURE::setGPIO (char port, int pin, int tim){                                 // Funktion zum Mappen des Port Pins auf die Alternative Funktion für den Timer Eingang
00088     
00089      GPIOchoose (port);                                                                 // Wählt den passenden Pointer zum Port aus
00090     
00091      portpo->MODER  |= (1 <<((2*pin)+1));                                              // Alternative Funktion 0x10 mit Maske (2 Bit pro Pin) 
00092      portpo->OTYPER |= (1 << pin);                                                     // Definition als Eingang 0x1 mit Open Drain 
00093      
00094          if(pin > 7){                                                                  // Ausgänge 8 bis 15 sind im höheren Register AFR[1]
00095             if(tim < 3){                                                               // Für Timer 1 und Timer 2 (Alternatve Funktion 01)
00096                  portpo->AFR[1] |= (1 << (4*(pin-8)));                                 // Alternative Funktion mit Maske für AF01
00097             }
00098             else{                                                                      // Für Timer 3, Timer 4 und Timer 5 (Alternative Funktion 10) 
00099                  portpo->AFR[1] |= (1 << (4*(pin-8))+1);                               // Alternative Funktion mit Maske für AF02          
00100             }   
00101          }
00102          else{                                                                         // Ausgänge 0 bis 7 sind im im unteren Register AFR[0]
00103             if(tim < 3){                                                               // Für Timer 1 und Timer 2 (Alternatve Funktion 01)
00104                  portpo->AFR[0] |= (1 << (4*pin));                                     // Alternative Funktion mit Maske für AF01
00105             }
00106             else{                                                                      // Für Timer 3, Timer 4 und Timer 5 (Alternative Funktion 10)  
00107                  portpo->AFR[0] |= (1 << ((4*pin)+1));                                 // Alternative Funktion mit Maske für AF02          
00108             }                       
00109          }            
00110     } 
00111 
00112 //====================================================================================================================================
00113 //                              Eventhandler für Timer und Externer Eingang
00114 //====================================================================================================================================
00115 
00116 void QUADRATURE::UPDATE_HANDLER (void){                                                  // Interrupt Service Routine für Update Events
00117     
00118             tipo->SR ^= 0x0001;                                                         // Flag löschen (Register xor mit Flag) 
00119 
00120         if (getTIM () > 1){     
00121                 TIMERCARRY--;                                                           // Carryvariable -1 da Unterlauf
00122          }
00123          else{
00124                 TIMERCARRY++;                                                           // Carryvariable 1 da Überlauf
00125              }  
00126              
00127         if(extfct == true){                                                             // Externe Funktion vorhanden?
00128                     (*IRQ_HANDLER_EXTERN)();                                            // Aufruf der Externen Funktion
00129             }               
00130     }
00131 
00132 
00133 //====================================================================================================================================
00134 //                              Setter- und Getter-Funktionen
00135 //====================================================================================================================================
00136 
00137 void QUADRATURE::startTIM (){
00138         NVIC_EnableIRQ(temp_ITM);                                                       // Enable den IRQ Handler
00139         tipo->CR1 = 0x0001;                                                             // Starte Timer
00140     }
00141     
00142 void QUADRATURE::stopTIM (){
00143         tipo->CR1 = 0x0000;                                                             // Stoppe Timer
00144         NVIC_DisableIRQ(temp_ITM);                                                      // Disable den IRQ Handler
00145     }
00146         
00147 unsigned int QUADRATURE::getTIM (){
00148         return   tipo->CNT;                                                             // Gibt aktuellen Timerwert zurück
00149     }
00150     
00151 signed short QUADRATURE::getCARRY (){
00152         return   TIMERCARRY;                                                            // Gibt aktuellen Timercarry zurück
00153     }
00154         
00155 void QUADRATURE::setTIM (int pre, int arr){
00156         tipo->PSC = pre;                                                                // Prescaler (Wert + 1)
00157         tipo->ARR = arr;                                                                // Auto reload   
00158     }
00159 
00160 void QUADRATURE::setUpRes (){
00161         
00162         GPIOchoose (CI1_PORT);                                                           // Wählt den passenden Pointer zum Port von CI1 aus  
00163         portpo->PUPDR  |= (1 << ((2*CI1_PIN)));                                         // Setzt den Pull up für den entsprechenden Port Pin von CI1
00164 
00165         GPIOchoose (CI2_PORT);                                                           // Wählt den passenden Pointer zum Port von CI2 aus  
00166         portpo->PUPDR  |= (1 << ((2*CI2_PIN)));                                         // Setzt den Pull up für den entsprechenden Port Pin von CI2                
00167     }
00168         
00169 void QUADRATURE::setDownRes (){
00170 
00171         GPIOchoose (CI1_PORT);                                                           // Wählt den passenden Pointer zum Port von CI1 aus    
00172         portpo->PUPDR  |= (1 << ((2*CI1_PIN)+1));                                       // Setzt den Pull down für den entsprechenden Port Pin von CI1
00173 
00174         GPIOchoose (CI2_PORT);                                                           // Wählt den passenden Pointer zum Port von CI2 aus 
00175         portpo->PUPDR  |= (1 << ((2*CI2_PIN)+1));                                       // Setzt den Pull down für den entsprechenden Port Pin von CI2           
00176     }
00177     
00178 void QUADRATURE::setIRQ_METHODE (void (*IRQ_HANDLER_METHODE)(void)){                     // Adresse zur externen Funktion übergeben und Freigabe setzen
00179           extfct = true;                                                                // Externe Funktion vorhanden. Freigabe setzen.
00180           IRQ_HANDLER_EXTERN = IRQ_HANDLER_METHODE;                                     // Funktionspointer der Funktion übernehmen       
00181     }
00182 
00183 
00184 //====================================================================================================================================
00185 //                             Hilfsfunktionen
00186 //====================================================================================================================================
00187     
00188 void QUADRATURE::GPIOchoose (char port){ 
00189   
00190         switch(port){                                                                   // Konfiguration jedes Ports durch Auswahl
00191                     case 'A':                                                           // Port A
00192                         RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;                            // Port A aktivieren
00193                         portpo = GPIOA;                                                 // Pointer auf Port A zuweisen
00194                     break;
00195                     
00196                     case 'B':                                                           // Port B
00197                         RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;                            // Port B aktivieren
00198                         portpo = GPIOB;                                                 // Pointer auf Port B zuweisen
00199                     break;
00200                     
00201                     case 'C':                                                           // Port C
00202                         RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;                            // Port C aktivieren
00203                         portpo = GPIOC;                                                 // Pointer auf Port C zuweisen
00204                     break;   
00205 
00206                     case 'D':                                                           // Port D
00207                         RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;                            // Port D aktivieren
00208                         portpo = GPIOD;                                                 // Pointer auf Port D zuweisen
00209                     break;                
00210 
00211                     case 'E':                                                           // Port E
00212                         RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;                            // Port E aktivieren
00213                         portpo = GPIOE;                                                 // Pointer auf Port E zuweisen
00214                     break;
00215                     
00216                     default:                                                            // kein Port ausgewählt und Fehlermeldung
00217                         printf("\n \n \r \n  Falscher Port ausgewahlt! \n \n \r");
00218                 }     
00219     }
00220     
00221 void QUADRATURE::_UPDATE_HANDLER(void)                                                  // ISR Handler für die Instanz
00222 {
00223     instance->UPDATE_HANDLER ();                                                         // Zuordnung des Handlers zum Handler der Instanz
00224     }
00225 
00226