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.cpp@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 | #include "QUADRATURE.h" |
ChrisselH | 0:1acdcc576936 | 3 | #include "cmsis_nvic.h" |
ChrisselH | 0:1acdcc576936 | 4 | |
ChrisselH | 0:1acdcc576936 | 5 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 6 | // Initialisieren und mappen der Kanäle, Timer etc |
ChrisselH | 0:1acdcc576936 | 7 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 8 | QUADRATURE *QUADRATURE::instance; // Pointer zur Adresse der Instanz |
ChrisselH | 0:1acdcc576936 | 9 | |
ChrisselH | 0:1acdcc576936 | 10 | |
ChrisselH | 0:1acdcc576936 | 11 | 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) |
ChrisselH | 0:1acdcc576936 | 12 | { |
ChrisselH | 0:1acdcc576936 | 13 | |
ChrisselH | 0:1acdcc576936 | 14 | TIMERCARRY = 0; // bei neuem Objekt den entsprechenden Timercarry auf 0 setzen |
ChrisselH | 0:1acdcc576936 | 15 | instance = this; // Instanz zuweisung zum neu generierten Objekt |
ChrisselH | 0:1acdcc576936 | 16 | extfct = false; // Externe Funktion bei Timer Interrupt deaktiviert |
ChrisselH | 0:1acdcc576936 | 17 | |
ChrisselH | 0:1acdcc576936 | 18 | //Konfiguration des Timers |
ChrisselH | 0:1acdcc576936 | 19 | switch(tim){ // Konfiguration jedes einzelnen Timers, durch Auswahl |
ChrisselH | 0:1acdcc576936 | 20 | case 1: // TIM1 |
ChrisselH | 0:1acdcc576936 | 21 | RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Timer 1 aktivieren |
ChrisselH | 0:1acdcc576936 | 22 | tipo = TIM1; // Pointer auf Timer1 zuweisen |
ChrisselH | 0:1acdcc576936 | 23 | temp_ITM = TIM1_UP_TIM10_IRQn; // NVIC Nummer für den Updateinterrupt Timer 1 |
ChrisselH | 0:1acdcc576936 | 24 | NVIC->ISER[0] &= ~(1 << TIM1_UP_TIM10_IRQn); // Interrupt Handler für den Timer 1 aktivieren |
ChrisselH | 0:1acdcc576936 | 25 | break; |
ChrisselH | 0:1acdcc576936 | 26 | |
ChrisselH | 0:1acdcc576936 | 27 | case 2: // TIM2 |
ChrisselH | 0:1acdcc576936 | 28 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // Timer 2 aktivieren |
ChrisselH | 0:1acdcc576936 | 29 | tipo = TIM2; // Pointer auf Timer2 zuweisen |
ChrisselH | 0:1acdcc576936 | 30 | temp_ITM = TIM2_IRQn; // NVIC Nummer für den Updateinterrupt Timer 2 |
ChrisselH | 0:1acdcc576936 | 31 | NVIC->ISER[0] &= ~(1 << TIM2_IRQn); // Interrupt Handler für den Timer 2 aktivieren |
ChrisselH | 0:1acdcc576936 | 32 | break; |
ChrisselH | 0:1acdcc576936 | 33 | |
ChrisselH | 0:1acdcc576936 | 34 | case 3: // TIM3 |
ChrisselH | 0:1acdcc576936 | 35 | RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // Timer 3 aktivieren |
ChrisselH | 0:1acdcc576936 | 36 | tipo = TIM3; // Pointer auf Timer3 zuweisen |
ChrisselH | 0:1acdcc576936 | 37 | temp_ITM = TIM3_IRQn; // NVIC Nummer für den Updateinterrupt Timer 3 |
ChrisselH | 0:1acdcc576936 | 38 | NVIC->ISER[0] &= ~(1 << TIM3_IRQn); // Interrupt Handler für den Timer 3 aktivieren |
ChrisselH | 0:1acdcc576936 | 39 | break; |
ChrisselH | 0:1acdcc576936 | 40 | |
ChrisselH | 0:1acdcc576936 | 41 | case 4: // TIM4 |
ChrisselH | 0:1acdcc576936 | 42 | RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // Timer 4 aktivieren |
ChrisselH | 0:1acdcc576936 | 43 | tipo = TIM4; // Pointer auf Timer4 zuweisen |
ChrisselH | 0:1acdcc576936 | 44 | temp_ITM = TIM4_IRQn; // NVIC Nummer für den Updateinterrupt Timer 4 |
ChrisselH | 0:1acdcc576936 | 45 | NVIC->ISER[0] &= ~(1 << TIM4_IRQn); // Interrupt Handler für den Timer 4 aktivieren |
ChrisselH | 0:1acdcc576936 | 46 | break; |
ChrisselH | 0:1acdcc576936 | 47 | |
ChrisselH | 0:1acdcc576936 | 48 | case 5: // TIM5 |
ChrisselH | 0:1acdcc576936 | 49 | RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; // Timer 5 aktivieren |
ChrisselH | 0:1acdcc576936 | 50 | tipo = TIM5; // Pointer auf Timer5 zuweisen |
ChrisselH | 0:1acdcc576936 | 51 | temp_ITM = TIM5_IRQn; // NVIC Nummer für den Updateinterrupt Timer 5 |
ChrisselH | 0:1acdcc576936 | 52 | NVIC->ISER[1] &= ~(1 << (TIM5_IRQn-31)); // Interrupt Handler für den Timer 5 aktivieren |
ChrisselH | 0:1acdcc576936 | 53 | break; |
ChrisselH | 0:1acdcc576936 | 54 | |
ChrisselH | 0:1acdcc576936 | 55 | default: // keinen Timer ausgewählt und Fehlermeldung |
ChrisselH | 0:1acdcc576936 | 56 | printf("\n \n \r \n Falscher Timer ausgewahlt! \n \n \r"); |
ChrisselH | 0:1acdcc576936 | 57 | return; |
ChrisselH | 0:1acdcc576936 | 58 | } |
ChrisselH | 0:1acdcc576936 | 59 | |
ChrisselH | 0:1acdcc576936 | 60 | tipo->SMCR = mode; // Schreibt den aktuellen Modus in das SMCR Register (Slave Mode) |
ChrisselH | 0:1acdcc576936 | 61 | tipo->CCMR1 = 0xF1F1; // Mappen der Capture Inputs 1 und 2 auf Timer Input 1 und 2 |
ChrisselH | 0:1acdcc576936 | 62 | tipo->CCMR2 = 0x0000; // Kein mappen der Capture Inputs 3 und 4 |
ChrisselH | 0:1acdcc576936 | 63 | tipo->CCER = 0x0011; // Capture Inputs 1 und 2 aktivieren |
ChrisselH | 0:1acdcc576936 | 64 | |
ChrisselH | 0:1acdcc576936 | 65 | // Konfiguration der Pins |
ChrisselH | 0:1acdcc576936 | 66 | setGPIO(CI1_PORT, CI1_PIN, tim); // Setzt den Port Pin für CI1 |
ChrisselH | 0:1acdcc576936 | 67 | setGPIO(CI2_PORT, CI2_PIN, tim); // Setzt den Port Pin für CI2 |
ChrisselH | 0:1acdcc576936 | 68 | |
ChrisselH | 0:1acdcc576936 | 69 | // Konfiguration der Polarität |
ChrisselH | 0:1acdcc576936 | 70 | if(CI1_POL == 1){ // Polarität für CI1 ändern auf fallende Flanke |
ChrisselH | 0:1acdcc576936 | 71 | tipo->CCER |= 0x0002; |
ChrisselH | 0:1acdcc576936 | 72 | } |
ChrisselH | 0:1acdcc576936 | 73 | if(CI2_POL == 1){ // Polarität für CI2 ändern auf fallende Flanke |
ChrisselH | 0:1acdcc576936 | 74 | tipo->CCER |= 0x0020; |
ChrisselH | 0:1acdcc576936 | 75 | } |
ChrisselH | 0:1acdcc576936 | 76 | |
ChrisselH | 0:1acdcc576936 | 77 | // Konfiguration der Interrupt Routine |
ChrisselH | 0:1acdcc576936 | 78 | NVIC_SetVector(temp_ITM, (uint32_t) &_UPDATE_HANDLER); // Adresse zum IRQ Handler des entsprechenden Timers |
ChrisselH | 0:1acdcc576936 | 79 | NVIC_SetPriority(temp_ITM, 0); // Festlegen der Priorität (Höchste, damit das nächste Increment mit gezählt wird) |
ChrisselH | 0:1acdcc576936 | 80 | tipo->DIER |= 0x0001; // Update Interrupt Einstellung im Timer aktivieren |
ChrisselH | 0:1acdcc576936 | 81 | |
ChrisselH | 0:1acdcc576936 | 82 | |
ChrisselH | 0:1acdcc576936 | 83 | } |
ChrisselH | 0:1acdcc576936 | 84 | |
ChrisselH | 0:1acdcc576936 | 85 | |
ChrisselH | 0:1acdcc576936 | 86 | |
ChrisselH | 0:1acdcc576936 | 87 | void QUADRATURE::setGPIO(char port, int pin, int tim){ // Funktion zum Mappen des Port Pins auf die Alternative Funktion für den Timer Eingang |
ChrisselH | 0:1acdcc576936 | 88 | |
ChrisselH | 0:1acdcc576936 | 89 | GPIOchoose(port); // Wählt den passenden Pointer zum Port aus |
ChrisselH | 0:1acdcc576936 | 90 | |
ChrisselH | 0:1acdcc576936 | 91 | portpo->MODER |= (1 <<((2*pin)+1)); // Alternative Funktion 0x10 mit Maske (2 Bit pro Pin) |
ChrisselH | 0:1acdcc576936 | 92 | portpo->OTYPER |= (1 << pin); // Definition als Eingang 0x1 mit Open Drain |
ChrisselH | 0:1acdcc576936 | 93 | |
ChrisselH | 0:1acdcc576936 | 94 | if(pin > 7){ // Ausgänge 8 bis 15 sind im höheren Register AFR[1] |
ChrisselH | 0:1acdcc576936 | 95 | if(tim < 3){ // Für Timer 1 und Timer 2 (Alternatve Funktion 01) |
ChrisselH | 0:1acdcc576936 | 96 | portpo->AFR[1] |= (1 << (4*(pin-8))); // Alternative Funktion mit Maske für AF01 |
ChrisselH | 0:1acdcc576936 | 97 | } |
ChrisselH | 0:1acdcc576936 | 98 | else{ // Für Timer 3, Timer 4 und Timer 5 (Alternative Funktion 10) |
ChrisselH | 0:1acdcc576936 | 99 | portpo->AFR[1] |= (1 << (4*(pin-8))+1); // Alternative Funktion mit Maske für AF02 |
ChrisselH | 0:1acdcc576936 | 100 | } |
ChrisselH | 0:1acdcc576936 | 101 | } |
ChrisselH | 0:1acdcc576936 | 102 | else{ // Ausgänge 0 bis 7 sind im im unteren Register AFR[0] |
ChrisselH | 0:1acdcc576936 | 103 | if(tim < 3){ // Für Timer 1 und Timer 2 (Alternatve Funktion 01) |
ChrisselH | 0:1acdcc576936 | 104 | portpo->AFR[0] |= (1 << (4*pin)); // Alternative Funktion mit Maske für AF01 |
ChrisselH | 0:1acdcc576936 | 105 | } |
ChrisselH | 0:1acdcc576936 | 106 | else{ // Für Timer 3, Timer 4 und Timer 5 (Alternative Funktion 10) |
ChrisselH | 0:1acdcc576936 | 107 | portpo->AFR[0] |= (1 << ((4*pin)+1)); // Alternative Funktion mit Maske für AF02 |
ChrisselH | 0:1acdcc576936 | 108 | } |
ChrisselH | 0:1acdcc576936 | 109 | } |
ChrisselH | 0:1acdcc576936 | 110 | } |
ChrisselH | 0:1acdcc576936 | 111 | |
ChrisselH | 0:1acdcc576936 | 112 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 113 | // Eventhandler für Timer und Externer Eingang |
ChrisselH | 0:1acdcc576936 | 114 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 115 | |
ChrisselH | 0:1acdcc576936 | 116 | void QUADRATURE::UPDATE_HANDLER(void){ // Interrupt Service Routine für Update Events |
ChrisselH | 0:1acdcc576936 | 117 | |
ChrisselH | 0:1acdcc576936 | 118 | tipo->SR ^= 0x0001; // Flag löschen (Register xor mit Flag) |
ChrisselH | 0:1acdcc576936 | 119 | |
ChrisselH | 0:1acdcc576936 | 120 | if (getTIM() > 1){ |
ChrisselH | 0:1acdcc576936 | 121 | TIMERCARRY--; // Carryvariable -1 da Unterlauf |
ChrisselH | 0:1acdcc576936 | 122 | } |
ChrisselH | 0:1acdcc576936 | 123 | else{ |
ChrisselH | 0:1acdcc576936 | 124 | TIMERCARRY++; // Carryvariable 1 da Überlauf |
ChrisselH | 0:1acdcc576936 | 125 | } |
ChrisselH | 0:1acdcc576936 | 126 | |
ChrisselH | 0:1acdcc576936 | 127 | if(extfct == true){ // Externe Funktion vorhanden? |
ChrisselH | 0:1acdcc576936 | 128 | (*IRQ_HANDLER_EXTERN)(); // Aufruf der Externen Funktion |
ChrisselH | 0:1acdcc576936 | 129 | } |
ChrisselH | 0:1acdcc576936 | 130 | } |
ChrisselH | 0:1acdcc576936 | 131 | |
ChrisselH | 0:1acdcc576936 | 132 | |
ChrisselH | 0:1acdcc576936 | 133 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 134 | // Setter- und Getter-Funktionen |
ChrisselH | 0:1acdcc576936 | 135 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 136 | |
ChrisselH | 0:1acdcc576936 | 137 | void QUADRATURE::startTIM(){ |
ChrisselH | 0:1acdcc576936 | 138 | NVIC_EnableIRQ(temp_ITM); // Enable den IRQ Handler |
ChrisselH | 0:1acdcc576936 | 139 | tipo->CR1 = 0x0001; // Starte Timer |
ChrisselH | 0:1acdcc576936 | 140 | } |
ChrisselH | 0:1acdcc576936 | 141 | |
ChrisselH | 0:1acdcc576936 | 142 | void QUADRATURE::stopTIM(){ |
ChrisselH | 0:1acdcc576936 | 143 | tipo->CR1 = 0x0000; // Stoppe Timer |
ChrisselH | 0:1acdcc576936 | 144 | NVIC_DisableIRQ(temp_ITM); // Disable den IRQ Handler |
ChrisselH | 0:1acdcc576936 | 145 | } |
ChrisselH | 0:1acdcc576936 | 146 | |
ChrisselH | 0:1acdcc576936 | 147 | unsigned int QUADRATURE::getTIM(){ |
ChrisselH | 0:1acdcc576936 | 148 | return tipo->CNT; // Gibt aktuellen Timerwert zurück |
ChrisselH | 0:1acdcc576936 | 149 | } |
ChrisselH | 0:1acdcc576936 | 150 | |
ChrisselH | 0:1acdcc576936 | 151 | signed short QUADRATURE::getCARRY(){ |
ChrisselH | 0:1acdcc576936 | 152 | return TIMERCARRY; // Gibt aktuellen Timercarry zurück |
ChrisselH | 0:1acdcc576936 | 153 | } |
ChrisselH | 0:1acdcc576936 | 154 | |
ChrisselH | 0:1acdcc576936 | 155 | void QUADRATURE::setTIM(int pre, int arr){ |
ChrisselH | 0:1acdcc576936 | 156 | tipo->PSC = pre; // Prescaler (Wert + 1) |
ChrisselH | 0:1acdcc576936 | 157 | tipo->ARR = arr; // Auto reload |
ChrisselH | 0:1acdcc576936 | 158 | } |
ChrisselH | 0:1acdcc576936 | 159 | |
ChrisselH | 0:1acdcc576936 | 160 | void QUADRATURE::setUpRes(){ |
ChrisselH | 0:1acdcc576936 | 161 | |
ChrisselH | 0:1acdcc576936 | 162 | GPIOchoose(CI1_PORT); // Wählt den passenden Pointer zum Port von CI1 aus |
ChrisselH | 0:1acdcc576936 | 163 | portpo->PUPDR |= (1 << ((2*CI1_PIN))); // Setzt den Pull up für den entsprechenden Port Pin von CI1 |
ChrisselH | 0:1acdcc576936 | 164 | |
ChrisselH | 0:1acdcc576936 | 165 | GPIOchoose(CI2_PORT); // Wählt den passenden Pointer zum Port von CI2 aus |
ChrisselH | 0:1acdcc576936 | 166 | portpo->PUPDR |= (1 << ((2*CI2_PIN))); // Setzt den Pull up für den entsprechenden Port Pin von CI2 |
ChrisselH | 0:1acdcc576936 | 167 | } |
ChrisselH | 0:1acdcc576936 | 168 | |
ChrisselH | 0:1acdcc576936 | 169 | void QUADRATURE::setDownRes(){ |
ChrisselH | 0:1acdcc576936 | 170 | |
ChrisselH | 0:1acdcc576936 | 171 | GPIOchoose(CI1_PORT); // Wählt den passenden Pointer zum Port von CI1 aus |
ChrisselH | 0:1acdcc576936 | 172 | portpo->PUPDR |= (1 << ((2*CI1_PIN)+1)); // Setzt den Pull down für den entsprechenden Port Pin von CI1 |
ChrisselH | 0:1acdcc576936 | 173 | |
ChrisselH | 0:1acdcc576936 | 174 | GPIOchoose(CI2_PORT); // Wählt den passenden Pointer zum Port von CI2 aus |
ChrisselH | 0:1acdcc576936 | 175 | portpo->PUPDR |= (1 << ((2*CI2_PIN)+1)); // Setzt den Pull down für den entsprechenden Port Pin von CI2 |
ChrisselH | 0:1acdcc576936 | 176 | } |
ChrisselH | 0:1acdcc576936 | 177 | |
ChrisselH | 0:1acdcc576936 | 178 | void QUADRATURE::setIRQ_METHODE(void (*IRQ_HANDLER_METHODE)(void)){ // Adresse zur externen Funktion übergeben und Freigabe setzen |
ChrisselH | 0:1acdcc576936 | 179 | extfct = true; // Externe Funktion vorhanden. Freigabe setzen. |
ChrisselH | 0:1acdcc576936 | 180 | IRQ_HANDLER_EXTERN = IRQ_HANDLER_METHODE; // Funktionspointer der Funktion übernehmen |
ChrisselH | 0:1acdcc576936 | 181 | } |
ChrisselH | 0:1acdcc576936 | 182 | |
ChrisselH | 0:1acdcc576936 | 183 | |
ChrisselH | 0:1acdcc576936 | 184 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 185 | // Hilfsfunktionen |
ChrisselH | 0:1acdcc576936 | 186 | //==================================================================================================================================== |
ChrisselH | 0:1acdcc576936 | 187 | |
ChrisselH | 0:1acdcc576936 | 188 | void QUADRATURE::GPIOchoose(char port){ |
ChrisselH | 0:1acdcc576936 | 189 | |
ChrisselH | 0:1acdcc576936 | 190 | switch(port){ // Konfiguration jedes Ports durch Auswahl |
ChrisselH | 0:1acdcc576936 | 191 | case 'A': // Port A |
ChrisselH | 0:1acdcc576936 | 192 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // Port A aktivieren |
ChrisselH | 0:1acdcc576936 | 193 | portpo = GPIOA; // Pointer auf Port A zuweisen |
ChrisselH | 0:1acdcc576936 | 194 | break; |
ChrisselH | 0:1acdcc576936 | 195 | |
ChrisselH | 0:1acdcc576936 | 196 | case 'B': // Port B |
ChrisselH | 0:1acdcc576936 | 197 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // Port B aktivieren |
ChrisselH | 0:1acdcc576936 | 198 | portpo = GPIOB; // Pointer auf Port B zuweisen |
ChrisselH | 0:1acdcc576936 | 199 | break; |
ChrisselH | 0:1acdcc576936 | 200 | |
ChrisselH | 0:1acdcc576936 | 201 | case 'C': // Port C |
ChrisselH | 0:1acdcc576936 | 202 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // Port C aktivieren |
ChrisselH | 0:1acdcc576936 | 203 | portpo = GPIOC; // Pointer auf Port C zuweisen |
ChrisselH | 0:1acdcc576936 | 204 | break; |
ChrisselH | 0:1acdcc576936 | 205 | |
ChrisselH | 0:1acdcc576936 | 206 | case 'D': // Port D |
ChrisselH | 0:1acdcc576936 | 207 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // Port D aktivieren |
ChrisselH | 0:1acdcc576936 | 208 | portpo = GPIOD; // Pointer auf Port D zuweisen |
ChrisselH | 0:1acdcc576936 | 209 | break; |
ChrisselH | 0:1acdcc576936 | 210 | |
ChrisselH | 0:1acdcc576936 | 211 | case 'E': // Port E |
ChrisselH | 0:1acdcc576936 | 212 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN; // Port E aktivieren |
ChrisselH | 0:1acdcc576936 | 213 | portpo = GPIOE; // Pointer auf Port E zuweisen |
ChrisselH | 0:1acdcc576936 | 214 | break; |
ChrisselH | 0:1acdcc576936 | 215 | |
ChrisselH | 0:1acdcc576936 | 216 | default: // kein Port ausgewählt und Fehlermeldung |
ChrisselH | 0:1acdcc576936 | 217 | printf("\n \n \r \n Falscher Port ausgewahlt! \n \n \r"); |
ChrisselH | 0:1acdcc576936 | 218 | } |
ChrisselH | 0:1acdcc576936 | 219 | } |
ChrisselH | 0:1acdcc576936 | 220 | |
ChrisselH | 0:1acdcc576936 | 221 | void QUADRATURE::_UPDATE_HANDLER(void) // ISR Handler für die Instanz |
ChrisselH | 0:1acdcc576936 | 222 | { |
ChrisselH | 0:1acdcc576936 | 223 | instance->UPDATE_HANDLER(); // Zuordnung des Handlers zum Handler der Instanz |
ChrisselH | 0:1acdcc576936 | 224 | } |
ChrisselH | 0:1acdcc576936 | 225 | |
ChrisselH | 0:1acdcc576936 | 226 |