Jens Altenburg / Mbed 2 deprecated Fachbuch_Initialisierungen

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /********************************************************************
00002  *
00003  *  Name:           main.cpp
00004  *  Beschreibung:   HAL für "Embedded Systems Engineering"
00005  *  Autor:
00006  *  Erstellung:     29.05.2020
00007  *
00008  *  Revisionsliste
00009  *  Datum       | Autor         | Änderung
00010  *  ------------+---------------+--------------------------
00011  *  29.05.2020  | Altenburg     | Ersterstellung
00012  *  ------------+---------------+--------------------------
00013  *  04.02.2021  | Altenburg     | syntaktische Korrekturen
00014  *  ------------+---------------+--------------------------
00015  *
00016  ********************************************************************/
00017 #include "mbed.h"
00018 #include "main.h"
00019 #include "oled.h"
00020 
00021 DigitalOut   pinLed4(PC_0);     /* SCL - I2C; rote LED2 */
00022 DigitalInOut pinLed2(PC_2);     /* SDA - I2C; grüne LED */
00023 
00024 DigitalOut   pinLed3(PC_7);     /* rote LED1 */
00025 
00026 /* Interruptprioritäten */
00027 #define nSystickLevel   31      /* niedrigste Priorität */
00028 #define nMillisecLevel  30      /* aufsteigende Priorität */
00029 #define nSbusTimerLevel 29
00030 #define nSbusUartLevel  28
00031 
00032 /* Interrupts global freigeben/sperren */
00033 #define mcIntEnable() \
00034     { __asm("  cpsie i\n"); }
00035 #define mcIntDisable() \
00036     { __asm("  cpsid i\n"); }
00037 
00038 void vWaitFast( void );          /* 200 ms Warten */
00039 void vWaitSlow( void );          /* 1 Sekunde warten */
00040 
00041 volatile word wTimer;/*
00042 * Description :
00043 */
00044 Def_fFunc afFuncList[] = { vWaitFast, vWaitSlow };/*
00045 * Description : Liste mit Funktionen
00046 */
00047 Def_fFunc *pafFuncList;/* 
00048 * Description : Zeiger auf Funktionspointerliste 
00049 */
00050 
00051 /****************************************************************************
00052  *                  Init Systemclock                                        * 
00053 PLLCFGR 0b00100010010000100010110100000100
00054 Reserved: 0
00055 PLLR:      010 = 2
00056 PLLQ:         0010 = 2
00057 Reserved:     0
00058 PLLSRC:        1 = HSE
00059 Reserved:       00 00
00060 PLLP:            10 = 6 
00061 PLLN:              0010110100 = 180
00062 PLLM:                    000100 = 4
00063 
00064 CFGR 0b00000000000000001011010000001111
00065 PPRE:              101 = AHB2 clock divided by 4
00066 PPRE:             101 = AHB1 clock divided by 4
00067 Reserved:            00 = 
00068 HPRE:                  0000 = AHB prescaler divided by 1
00069 SWS:                   11 = PLL_R used as the system clock
00070 SW:                  11 = PLL_R selected as system clock
00071 
00072  *      Author  :   J. Altenburg (based on C. Hilgert)                      *
00073  *      Revison :   17.07.17                                                *
00074  *      Parameters                                                          *
00075  *      Input   :   Nothing                                                 *
00076  *      Output  :   Nothing                                                 *
00077  ****************************************************************************/
00078 void vSysClockInit(void) {
00079     volatile dword dw;
00080     RCC->APB1ENR |= RCC_APB1ENR_PWREN;      /* __PWR_CLK_ENABLE(); */
00081     PWR->CR |= 0x0000C000;                  /* VOS[1:0] Scale 1 = 0b11 */
00082     dw = RCC->PLLCFGR;
00083     dw = 0x22422d04;                        /* PLLCFG-Register einstellen */
00084     RCC->PLLCFGR = dw;
00085     PWR->CR |= PWR_CR_ODEN;                 /* overdrive enable */
00086     while ((PWR->CSR & PWR_CSR_ODRDY) == 0);/* wait until overdrive is ready */
00087     PWR->CR |= PWR_CR_ODSWEN;
00088     RCC->CR |= RCC_CR_HSEON;                /* 1. Clocking the controller from external HSC crystal (8 MHz) */
00089     while ((RCC->CR & RCC_CR_HSERDY) == 0); /* wait until the HSE is ready */
00090     RCC->CR |= RCC_CR_PLLON;                /* 2. PLL on */
00091     while ((RCC->CR & RCC_CR_PLLRDY) == 0); /* wait until PLL is locked */
00092     FLASH->ACR = FLASH_ACR_LATENCY_5WS;     /* Zugriffsverz?gerung */
00093     dw = RCC->CFGR;
00094     dw |= (RCC_CFGR_PPRE2_DIV4 | RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_PLLR);
00095     RCC->CFGR = dw;                         /* APB2 = 45 MHz, APB1 = 45 MHz */
00096     }
00097 
00098 /****************************************************************************
00099  *                  Init-Port - A                                           * 
00100  *      Author  :   J. Altenburg (based on C. Hilgert)                      *
00101  *      Revison :   17.07.17                                                *
00102  *      Parameters                                                          *
00103  *      Input   :   Nothing                                                 *
00104  *      Output  :   Nothing                                                 *
00105  *      Hinweis :   Beschreibung GPIO_AFR[x] Table 11 im Datasheet          *
00106  ****************************************************************************/
00107 void vPortAInit(void) {
00108     dword dw;
00109     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;    /* GPIO-Port A initialisieren */
00110     dw = GPIOA->MODER;
00111     dw &= ~(GPIO_MODER_MODE15_Msk   /* PA15 maskieren */
00112             | GPIO_MODER_MODE0_Msk  /* PA0 - UART4 TX */
00113             | GPIO_MODER_MODE1_Msk  /* PA1 - UART4 RX */
00114             | GPIO_MODER_MODE2_Msk  /* PA2 - UART2 TX */
00115             | GPIO_MODER_MODE3_Msk  /* PA3 - UART2 RX */
00116             | GPIO_MODER_MODE4_Msk  /* PA4 - SPI1_CS  */
00117             | GPIO_MODER_MODE5_Msk  /* PA5 - SPI1 SCK */
00118             | GPIO_MODER_MODE6_Msk  /* PA6 - SPI1 MISO */
00119             | GPIO_MODER_MODE7_Msk  /* PA7 - SPI1 MOSI */
00120             | GPIO_MODER_MODE9_Msk  /* PA9 - UART1 TX */
00121             | GPIO_MODER_MODE10_Msk /* PA10- UART1 RX */
00122         );
00123     dw |= (GPIO_MODER_MODE15_0   /* PA15- output */
00124            | GPIO_MODER_MODE0_1  /* PA0 - alternate output */
00125            | GPIO_MODER_MODE1_1  /* PA1 - alternate output */
00126            | GPIO_MODER_MODE2_1  /* PA2 - alternate output */
00127            | GPIO_MODER_MODE3_1  /* PA3 - alternate output */
00128            | GPIO_MODER_MODE4_0  /* PA4 - output */
00129            | GPIO_MODER_MODE5_1  /* PA5 - alternate output */
00130            | GPIO_MODER_MODE6_1  /* PA6 - alternate output */
00131            | GPIO_MODER_MODE7_1  /* PA7 - alternate output */
00132            | GPIO_MODER_MODE9_1  /* PA9 - alternate output */
00133            | GPIO_MODER_MODE10_1 /* PA10- alternate output */
00134         );
00135     GPIOA->MODER = dw;
00136     dw = GPIOA->OTYPER;
00137     dw |= GPIO_OTYPER_OT15; /* open drain */
00138     //GPIOA->OTYPER = dw;
00139     dw = GPIOA->OSPEEDR;
00140     dw |= GPIO_OSPEEDR_OSPEED15_1;
00141 
00142     GPIOA->AFR[0] = 0x55507788;
00143     GPIOA->AFR[1] = 0x00000770;
00144     //vCS1High(); /* CS BME280 inaktiv */
00145 }
00146 
00147 /***************************************************************************
00148 *                  Init Systemticker                                   
00149 *      Author  :   J. Altenburg               
00150 *      Revison :   17.07.17                                      
00151 *      Parameters – alle 15 Millisekunden einen Interrupt       
00152 ***************************************************************************/
00153 void vSystickInit( void ) {
00154     NVIC_SetPriority(SysTick_IRQn, nSystickLevel); /* INT freigeben */
00155     /* 15m/180MHz^-1 set reload register = 15 Millisekunden */
00156     SysTick->LOAD = (2700000 - 1); 
00157     SysTick->VAL = 0;               /* Init Counter */
00158     SysTick->CTRL = ( SysTick_CTRL_ENABLE_Msk
00159                      |SysTick_CTRL_CLKSOURCE_Msk
00160                      |SysTick_CTRL_TICKINT_Msk
00161                      );
00162     }
00163 
00164 
00165 /****************************************************************************
00166  *                  Timer2                                                  * 
00167  *      Author  :   J. Altenburg                                            *
00168  *      Revison :   18.07.17                                                *
00169  *      Parameters                                                          *
00170  *      Input   :   Nothing                                                 *
00171  *      Output  :   Nothing                                                 *
00172  ****************************************************************************/
00173 void vTimer2Init(void) {
00174     RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; /* Power on */
00175     TIM2->PSC = 8;                      /* 90MHz^-1 * (8+1) = 100 ns */
00176     TIM2->ARR = 60000;                  /* 100ns * 10000 = 1 ms */
00177     TIM2->CR1 &= ~TIM_CR1_DIR;          /* aufw?rts z?hlen */
00178     //TIM2->CCR1  = 20000;
00179     NVIC_SetPriority(TIM2_IRQn, nMillisecLevel);
00180     NVIC_EnableIRQ(TIM2_IRQn);
00181     TIM2->DIER = TIM_DIER_CC1IE; /* compare interrupt enable */
00182     TIM2->CR1 |= TIM_CR1_CEN;
00183     }
00184 
00185 /****************************************************************************
00186  *                  Timer4 als Interruptquelle Uhrzeiger-Arithmetik         * 
00187  *      Author  :   J. Altenburg                                            *
00188  *      Revison :   21.05.20                                                *
00189  *      Parameters                                                          *
00190  *      Input   :   Nothing                                                 *
00191  *      Output  :   Nothing                                                 *
00192  ****************************************************************************/
00193 void vTimer4Init(void) {
00194     RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; /* Power on */
00195     TIM4->PSC = 8;                      /* 90MHz^-1 * (8+1) = 100 ns */
00196     TIM4->ARR = 0xffff;                  /* 100ns * 10000 = 1 ms */
00197     TIM4->CR1 &= ~TIM_CR1_DIR;          /* aufwärts zählen */
00198     TIM4->CCR1  = 15000;
00199     NVIC_SetPriority(TIM4_IRQn, nMillisecLevel);
00200     NVIC_EnableIRQ(TIM4_IRQn);
00201     TIM4->DIER = TIM_DIER_CC1IE;        /* compare interrupt enable */
00202     TIM4->CR1 |= TIM_CR1_CEN;
00203 }
00204 
00205 /****************************************************************************
00206  *                  UART 2                              
00207  *      Author  :   J. Altenburg 
00208  *      Revison :   20.07.17                                               
00209  ****************************************************************************/
00210 void vUart2Init(void) {
00211     RCC->APB1ENR |= RCC_APB1ENR_USART2EN; /* UART2 freigeben */
00212     USART2->CR3 = 0;                      /* Reset-Value */
00213     /* 1 Stop Bit; Keine Parität; 8-Databits */
00214     USART2->CR1 |= (USART_CR1_UE + USART_CR1_RXNEIE + USART_CR1_RE + USART_CR1_TCIE + USART_CR1_TE);
00215     /* Baudrate UART */
00216     /* Bit 0-3 sind Fraction->Kommazahl; 15-4 sind Mantissa->ganze Zahl */
00217     /* UARTDIV = f/(Baud*16); UART5->BRR = UARTDIV << 4 | UARTDIV_Komma */
00218     /* 146.48 = 45MHz/(19200 * 16) */
00219     USART2->BRR = (word)((146 << 4) | 5);
00220 #if 0
00221     NVIC_SetPriority(USART2_IRQn, nMillisecLevel); /* Prioritaet */
00222     NVIC_EnableIRQ(USART2_IRQn);
00223 #endif
00224 }
00225 
00226 
00227 
00228 /****************************************************************************
00229  *                  ISR - Systemtimer                                       *
00230  *                  - Aufruf der APPs alle x ms                             * 
00231  *                  - Aufruf des "Millisekunden"-Containers                 *           
00232  *      Author  :   J. Altenburg                                            *
00233  *      Revison :   17.07.17                                                *
00234  ****************************************************************************/
00235 extern "C" void SysTick_Handler( void ){
00236     SysTick->CTRL &= ~SysTick_CTRL_COUNTFLAG_Msk;
00237     //GPIOA->ODR ^= (1<<15); /* Testsignal auf GPIO legen */
00238     }
00239 
00240 
00241 /****************************************************************************
00242  *                  ISR - Timer 2                                           *
00243  *      Author  :   J. Altenburg                                            *
00244  *      Revison :   30.08.17                                                *
00245  *      Parameters                                                          *
00246  *      Laufzeit:   x.y µs                                       *
00247  ****************************************************************************/
00248 extern "C" void TIM2_IRQHandler(void) {
00249     //volatile word w;
00250     TIM2->SR &= ~TIM_SR_CC1IF; /* clear pending bit (sicherheitshalber) */
00251     //TIM2->CCR1 += 10000;
00252     //GPIOA->ODR ^= (1<<15);
00253     //pinLed2 = !pinLed2;
00254     }
00255 
00256 /****************************************************************************
00257  *                  ISR - Timer 4                                           *
00258  *      Author  :   J. Altenburg                                            *
00259  *      Revison :   30.08.17                                                *
00260  *      Parameters                                                          *
00261  *      Laufzeit:   x.y µs                                       *
00262  ****************************************************************************/
00263 extern "C" void TIM4_IRQHandler(void) {
00264     //volatile word w;
00265     TIM4->SR &= ~TIM_SR_CC1IF; /* clear pending bit (sicherheitshalber) */
00266     TIM4->CCR1  += wTimer;
00267     wTimer += 1500;
00268     //GPIOA->ODR ^= (1<<15); /* Testsignal auf GPIO legen */
00269     }
00270 
00271 /* I2C - Zugriff */
00272 void vSDAOutput( void ){        /* SDA-Datenrichtung -> Output */
00273     pinLed2.output();           /* auf Ausgang setzen */
00274     }
00275     
00276 void vSDAInput( void ){         /* SDA-Datenrichtung -> Input */
00277     pinLed2.input();            /* auf Ausgang setzen */
00278     }
00279 
00280 void vSDA_H( void ){            /* SDA setzen */
00281     pinLed2 = On;
00282     }
00283     
00284 void vSDA_L( void ){            /* SDA löschen */
00285     pinLed2 = Off;
00286     }
00287     
00288 void vSCL_H( void ){            /* SCL setzen */
00289     pinLed4 = On;
00290     }
00291     
00292 void vSCL_L( void ){            /* SCL löschen */
00293     pinLed4 = Off;
00294     }
00295 
00296 
00297 void vI2CDelay( void ){         /* ca. 5µs Verzögerung */
00298     volatile word wDelay = 6;
00299     while(wDelay--);
00300     }
00301 
00302 void vI2CShort( void ){         /* ca. 5µs Verzögerung */
00303     volatile word wDelay = 2;
00304     while(wDelay--);
00305     }
00306 /* schnelles Blinken */
00307 void vWaitFast( void ){
00308     wait(0.2);
00309     }
00310 
00311 /* langsames Blinken */
00312 void vWaitSlow( void ){         
00313     wait(1);
00314     }
00315 
00316 Def_stValue stRaw1 = {1,1,1,1,1,1,1,1};
00317 Def_stValue stRaw2 = {2,2,2,2,2,2,2,2};
00318 
00319 byte bAverage1(Def_stValue stLocal){
00320     byte i, j = 0;
00321     for(i = 0; i < 8; i++){
00322         j = j + stLocal.abData[i];
00323         }
00324     return j>>3;
00325     }
00326 
00327 void vAverage2(byte *pAverage, Def_stValue *stLocal){
00328     byte i, j = 0;
00329     for(i = 0; i < 8; i++){
00330         j = j + stLocal->abData[i];
00331         }
00332     *pAverage = (j>>3);
00333     }
00334 
00335 
00336 int main() {
00337     byte abText[] = "Hallo OLED!";
00338     dword dwTime = 11;
00339     byte bPos = 0;
00340     byte i = 'A';
00341     byte y = 0;
00342     pinLed2.mode(OpenDrain);    /* bidirektionaler Pin */ 
00343     //pinLed2.output();           /* auf Ausgang setzen */
00344     mcIntDisable();
00345     vSysClockInit();
00346     vPortAInit();
00347     vSystickInit();
00348     vTimer2Init();
00349     vTimer4Init();
00350     vUart2Init();
00351     mcIntEnable();
00352     vOledInit();
00353     ssd1306_fill4(255, 255, 255, 255);
00354     ssd1306_fill4(0, 0, 0, 0);
00355     pafFuncList = &afFuncList[0];              /* referenzieren auf Liste */
00356     y = bAverage1(stRaw1);
00357     ssd1306tx_large(y+'0', 4, 10);
00358     vAverage2(&y, &stRaw2);
00359     ssd1306tx_large(y+'0', 4, 2);
00360     y = 1;
00361     while(1) {
00362 #if 1
00363         bPos = 0;
00364         for(i = 0; i < sizeof(abText)-1; i++){
00365             pinLed3 = 0;
00366             ssd1306tx_large(abText[i], bPos, 6);
00367             bPos = bPos + 9;
00368             pinLed3 = 1;
00369             USART2->DR = 'J';
00370             (*(pafFuncList + y))();             /* unterschiedliche Wartezeiten */
00371             dwTime--;
00372             if(dwTime == 0){
00373                 dwTime = 11;
00374                 (y == 0) ? y = 1 : y = 0;
00375                 ssd1306_fill4(0, 0, 0, 0);
00376                 }
00377             GPIOA->ODR ^= (1<<15);
00378             }
00379 #else
00380         dwTime = 10000000;
00381         while(dwTime--);
00382         pinLed3 = 0;
00383         ssd1306_setpos(0,0);
00384         //ssd1306_setpos(bPos, y);
00385         //ssd1306tx_char(i);
00386         ssd1306tx_large(i, bPos, y);
00387         pinLed3 = 1;
00388         if(i < 'Z') i++;
00389         else        i = 'A'; 
00390         bPos = bPos + 9;
00391         y = y + 2;
00392 #endif
00393         }
00394     }