Sunday 19 November 2017

zSTM32L152RC

20171119.7     To be edited.

STM32L152RC

20170628.3

==========
Buy an STM32 L1 Discovery (STM32L152C-DISCO) board.
Buy an USB A to mini B cable.

Download and install Keil MDK523.
Run PackInstaller, and install the software pack for STM32L1xx.
Install the STLink driver, if necessary.


Connect the board to the computer.

Run MDK523, create a new project for STM32L152RC, including the CORE and Startup components.
Select ST-Link Debugger with the 'SW' port for the Target.

Edit and add the following code as the source file:

          int main(void){

          }

Rebuild.
Start Debug Session.
Stop Debug Session.

==========
Edit the source file as

//   Port B bit 6 Output
#include "stm32l1xx.h"  

int main(void){
  
        RCC->AHBENR        |=        RCC_AHBENR_GPIOBEN ;                  
        GPIOB->MODER    &=        ~( 0x03<<(2*6) ) ;        // Clear MODE Mask
        GPIOB->MODER    |=        0x01<<(2*6) ;         // Output(01)     
        GPIOB->ODR        |=        1<<6 ;                     // Set bit

        while(1);
}
Rebuild.
Start Debug Session.
The blue LED on the right should be lighted.
Stop Debug Session.

==========

Edit the source file as

//   Port B bit 6 Output  blinking
#include "stm32l1xx.h"  

int main(void){
        int i,j;
  
        RCC->AHBENR        |=        RCC_AHBENR_GPIOBEN ;                  
        GPIOB->MODER    &=        ~( 0x03<<(2*6) ) ;        // Clear MODE Mask
        GPIOB->MODER    |=        0x01<<(2*6) ;         // Output(01)     
        GPIOB->ODR        &=        ~(1<<6) ;                // Clear bit

    while(1){
        for(i=0;i<=100;i++){for(j=0;j<=1000;j++);}
        GPIOB->ODR        |=        1<<6 ;                     // Set bit
        for(i=0;i<=100;i++){for(j=0;j<=1000;j++);}
        GPIOB->ODR        &=        ~(1<<6) ;                // Clear bit
        }
        while(1);
}

Rebuild and debug.
The LED would blink.

==========





==========================================================
==========================================================
==========================================================

2015.01.08=4
==========================================================
Introduction
This is a revised blog, for beginners, on the STM32L152 microcontroller based on the new STM32L152C-DISCO starter kit. What you learn on the STM32L152 may be used for the other STM32 microcontrollers.
To use the starter kit, it is necessary to download, and read, materials from the internet and to write simple programs in C language. Basic knowledge on electronics, binary numbers and logic operations are assumed. The Keil uV5 IDE is used for writing and downloading the programs.
Materials to be downloaded include the followings:
UM1079  User Manual STM32L-Discovery
RM0038  Reference Manual  …STM32L1… MCUs
KEIL MDK512 (uV5 IDE)
Cortex-M3  Technical Reference Manual (r2p1)
==========================================================
How to start
Install the uV5 IDE in an easily accessible folder, including the STM32L1xx pack.
Connect the starter kit to the computer.
Create a suitable folder for the project.
Search, from the pack, the file STM32L1xx.h and copy it into the folder.
Launch the uV5 IDE.
Create a new Project for STM32L152RC, include the CORE and Startup files.
In ‘Options for Project’, use ST-Link as the debugger with “SW” setting.
Edit and add the following code or program, as a file, into the project.
//     P11PBO22.c    Port B Output 
#include "stm32l1xx.h"
int main(void){
       RCC->AHBENR   |=     RCC_AHBENR_GPIOBEN ;                    
       GPIOB->MODER  |=    0x01<<(2*6) ;         // Output(01)
       GPIOB->ODR    |=       1<<6 ;             // Set bit 
       while(1);
}
 
Rebuild, Start Debug Session and Run.
The blue LED will be turned ON.
==========================================================
LCD on board  
For the 96-segment LCD on the kit please see  https://programmingmicrocontrollerskohcs.blogspot.sg/

The writing below will be moved to the above site later.
==========================================================
Timing  
It is time to take over the timing of the microcontroller.
The following program configures the clock from the MSI and generates 1-second intervals using Timer 9.
//  P33T9I14.c  Timer 9 Interrupt  MSI = 4.194 MHz
#include "stm32l1xx.h"
void N_LCD(long M);
void UserInit(void);
long RAM24[4];
int C8[]={0x3F,0x06,0xDB,0xCF,0xE6,0xED,0xFD,0x07,0xFF,0xEF,0x06,0xDB} ;
int sec,secflag ;
int main(){
       UserInit();
      
  NVIC->ISER[0]      |= 1<<TIM9_IRQn ; 
      
       sec = -5 ;
       N_LCD(sec);
       secflag = 0 ;
       while(1){                                                                         // Wait for interrupts
              while(secflag==0);
              secflag = 0 ;
              sec++ ;
              N_LCD(sec);
       }
}
void TIM9_IRQHandler(void){
    TIM9->SR &= ~TIM_SR_UIF;             // Clear Timer Flag
              secflag = 1 ;
}
void map8to8(int q, int L){              // L=0 : Rightmost digit
       if((q&0x01)==0x01) RAM24[1] |= 0x01<<(12+2*L) ;        // A +
       if((q&0x02)==0x02) RAM24[0] |= 0x01<<(12+2*L) ;        // B +
       if((q&0x04)==0x04) RAM24[1] |= 0x01<<(11-2*L) ;        // C
       if((q&0x08)==0x08) RAM24[1] |= 0x01<<(10-2*L) ;        // D
       if((q&0x10)==0x10) RAM24[0] |= 0x01<<(10-2*L) ;        // E
       if((q&0x20)==0x20) RAM24[1] |= 0x01<<(13+2*L) ;        // F +
       if((q&0x40)==0x40) RAM24[0] |= 0x01<<(13+2*L) ;        // G +
       if((q&0x80)==0x80) RAM24[0] |= 0x01<<(11-2*L) ;        // M 
}     
void LCD96map(void){
       int b ;                   
                  
           //  b = 0,1,2, 3,4,5, 6, 7, 8, 9,10,11, 12,13,14,15,16,17, 18,19,20,21,22,23
       char MAP[]={0,1,2, 7,8,9,10,11,12,13,14,15, 17,16,18,19,20,21, 24,25,26,27,28,29};
       // Bits     3,4,5,6,               22,23,            30,31 not used
              LCD->RAM[0*2]  = 0 ;
              LCD->RAM[1*2]  = 0 ;
              LCD->RAM[2*2]  = 0 ;
              LCD->RAM[3*2]  = 0 ;
              for(b=0;b<=23;b++){
                     LCD->RAM[0*2] |=  (RAM24[0]&(1<<b))<<(MAP[b]-b);
                     LCD->RAM[1*2] |=  (RAM24[1]&(1<<b))<<(MAP[b]-b);
                     LCD->RAM[2*2] |=  (RAM24[2]&(1<<b))<<(MAP[b]-b);
                     LCD->RAM[3*2] |=  (RAM24[3]&(1<<b))<<(MAP[b]-b);
              }
}
void N_LCD(long M){
       int t ;
      
       RAM24[0] = 0 ;
       RAM24[1] = 0 ;
       if( (M<=999999) && (M>=0) ) {
              t = 0 ;
              while(M>99999){
                     M = M - 100000 ;
                     t++ ;
              }
              map8to8(C8[t],5);
              t = 0 ;
              while(M>9999){
                     M = M - 10000 ;
                     t++ ;
              }
              map8to8(C8[t],4);         
              t = 0 ;
              while(M>999){
                     M = M - 1000 ;
                     t++ ;
              }
              map8to8(C8[t],3);
              t = 0 ;
              while(M>99){
                     M = M - 100 ;
                     t++ ;
              }
              map8to8(C8[t],2);
             
              t = 0 ;
              while(M>9){
                     M = M - 10 ;
                     t++ ;
              }
              map8to8(C8[t],1);         
              t = M ;
              map8to8(C8[t],0);         
              LCD96map();
              LCD->SR       |=     LCD_SR_UDR ;
              while( (LCD->SR&LCD_SR_UDD)==0 );
       }
       else{
              map8to8(0xC0,0);
              LCD96map();
              LCD->SR       |=     LCD_SR_UDR ;
              while( (LCD->SR&LCD_SR_UDD)==0 );
       }
}
void PAaft(char PIN, char FUNC){         // Port A alternate function
  GPIOA->MODER       &=  ~(0x03<<(2*PIN)) ;     // Clear Mode mask 
  GPIOA->MODER       |=    0x02<<(2*PIN)  ;     // 0=i; 1=O; 2=AltFun; 3=Analog  
  if(PIN<=7){
    GPIOA->AFR[0]    &=  ~(0x0F<<(4*PIN)) ;            // Clear AFR mask
    GPIOA->AFR[0]    |=    FUNC<<(4*PIN) ;             // Alt Func
      } else{
    GPIOA->AFR[1]    &=  ~(0x0F<<(4*(PIN-8))); // Clear AFR mask
    GPIOA->AFR[1]    |=    FUNC<<(4*(PIN-8)) ; // Alt Func
  } 
}                                
void PBaft(char PIN, char FUNC){         // Port B alternate function
  GPIOB->MODER       &=  ~(0x03<<(2*PIN)) ;     // Clear Mode mask 
  GPIOB->MODER       |=    0x02<<(2*PIN)  ;     // 0=i; 1=O; 2=AltFun; 3=Analog  
  if(PIN<=7){
    GPIOB->AFR[0]    &=  ~(0x0F<<(4*PIN)) ;            // Clear AFR mask
    GPIOB->AFR[0]    |=    FUNC<<(4*PIN) ;             // Alt Func
      } else{
    GPIOB->AFR[1]    &=  ~(0x0F<<(4*(PIN-8))); // Clear AFR mask
    GPIOB->AFR[1]    |=    FUNC<<(4*(PIN-8)) ; // Alt Func
  } 
}
void PCaft(char PIN, char FUNC){         // Port C alternate function
       GPIOC->MODER         &=  ~(0x03<<(2*PIN)) ;     // Clear Mode mask 
       GPIOC->MODER         |=    0x02<<(2*PIN) ;      // 0=i; 1=O; 2=AltFun; 3=Analog  
       if(PIN<=7){
              GPIOC->AFR[0] &=  ~(0x0F<<(4*PIN)) ;            // Clear AFR mask
              GPIOC->AFR[0]        |=    FUNC<<(4*PIN) ;             // Alt Func
              } else{
              GPIOC->AFR[1]        &=  ~(0x0F<<(4*(PIN-8))); // Clear AFR mask
              GPIOC->AFR[1]        |=    FUNC<<(4*(PIN-8)) ; // Alt Func
              } 
}
void LCD96conf(void){
       char i ;
       char Apins[]={1,2,3,8,9,10,15};          // 7 pins
       char Bpins[]={3,4,5,8,9,10,11,12,13,14,15};     // 11 pins
       char Cpins[]={0,1,2,3,6,7,8,9,10,11};           // 10 pins
       //  LCD on Board  Configuration
       RCC->AHBENR  |=  RCC_AHBENR_GPIOAEN ;  
       RCC->AHBENR   |=  RCC_AHBENR_GPIOBEN ;                
       RCC->AHBENR          |=  RCC_AHBENR_GPIOCEN ;                
       for(i=0;i<=6;i++) { PAaft(Apins[i],11);  }
       for(i=0;i<=10;i++){ PBaft(Bpins[i],11);  }
       for(i=0;i<=9;i++) { PCaft(Cpins[i],11);  }
       RCC->APB1ENR  |=  RCC_APB1ENR_LCDEN ;   
       LCD->CR              =      LCD_CR_MUX_SEG | 0x0C | 0x40 ;    // Duty=1/4 Bias=1/3  64-pin !
       LCD->FCR      =  0 ;                    // Reset condition
       LCD->FCR      |=     (4<<22) ;     // PS = 4  (Bits 22,23,24,25)
       LCD->FCR      |=     (1<<18) ;     // DIV = 1  (Bits 18,19,20,21)
       LCD->FCR      |=     (7<<10) ;     // CC = 7  (Bits 10,11,12)
       LCD->FCR      |=     (7<<4) ;      // PON = 7  (Bits 4,5,6)
       LCD->CR              |=     LCD_CR_LCDEN ;
       while( (LCD->SR&LCD_SR_RDY)==0 ); // Wait till ready
       RAM24[0] = 0 ;
       RAM24[1] = 0 ;
       RAM24[2] = 0 ;
       RAM24[3] = 0 ;
}
void UserInit(void){
       //  Enable LSI for LCD                                                                                           
       RCC->APB1ENR  |=     RCC_APB1ENR_PWREN ;
       PWR->CR                    |=     PWR_CR_DBP ;
       RCC->CSR             |=     RCC_CSR_LSION ;
       while( (RCC->CSR&RCC_CSR_LSIRDY)==0 );   // Wait till LSE Ready    
       RCC->CSR             &=     ~RCC_CSR_RTCSEL      ;                          // Mask
       RCC->CSR             |=     RCC_CSR_RTCSEL_LSI  ;     
      
       LCD96conf();
      
       //  MSI 
  RCC->CR     |=      RCC_CR_MSION ;
  while( (RCC->CR&RCC_CR_MSIRDY)==0 );                        // Wait till MSI Ready
       RCC->ICSCR    =  (RCC->ICSCR&(~RCC_ICSCR_MSIRANGE)) | RCC_ICSCR_MSIRANGE_6 ;       // 000--> 110
  RCC->CFGR   &=     ~RCC_CFGR_SW ;                           // Clock Switch Mask
  RCC->CFGR   |=     RCC_CFGR_SW_MSI ;                        // Switch to MSI
  while( (RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_MSI );        // Wait till MSI
       //  Timer9  Configuration
       RCC->APB2ENR  |=  RCC_APB2ENR_TIM9EN ; 
       TIM9->PSC = 4194 - 1 ;             // Prescaler=4194 --> 1 kHz
       TIM9->ARR = 1000 - 1 ;             // 1000  --> 1 s
       TIM9->CR1     |= TIM_CR1_CEN ;     // Enable Timer
       TIM9->SR      &= ~TIM_SR_UIF;      // Clear Timer Flag
       TIM9->DIER    |= TIM_DIER_UIE ;    // Enable Timer Interrupt
}
The program appears long. But most of the codes are for the LCD.
==========================================================
Clock  
Then the core voltage, the wait state and PLL can be implemented.
The HSI is used, as the HSE requires some soldering.
//  P35PLL14.c  Core Voltage  Wait State  HSI  PLL at 32 MHz
#include "stm32l1xx.h"
void N_LCD(long M);
void UserInit(void);
long RAM24[4];
int C8[]={0x3F,0x06,0xDB,0xCF,0xE6,0xED,0xFD,0x07,0xFF,0xEF,0x06,0xDB} ;
int sec,secflag ;
int main(){
       UserInit();
      
  NVIC->ISER[0]      |= 1<<TIM9_IRQn ; 
      
       sec = -5 ;
       N_LCD(sec);
       secflag = 0 ;
       while(1){                                                                         // Wait for interrupts
              while(secflag==0);
              secflag = 0 ;
              sec++ ;
              N_LCD(sec);
       }
}
void TIM9_IRQHandler(void){
    TIM9->SR &= ~TIM_SR_UIF;             // Clear Timer Flag
              secflag = 1 ;
}
void map8to8(int q, int L){              // L=0 : Rightmost digit
       if((q&0x01)==0x01) RAM24[1] |= 0x01<<(12+2*L) ;        // A +
       if((q&0x02)==0x02) RAM24[0] |= 0x01<<(12+2*L) ;        // B +
       if((q&0x04)==0x04) RAM24[1] |= 0x01<<(11-2*L) ;        // C
       if((q&0x08)==0x08) RAM24[1] |= 0x01<<(10-2*L) ;        // D
       if((q&0x10)==0x10) RAM24[0] |= 0x01<<(10-2*L) ;        // E
       if((q&0x20)==0x20) RAM24[1] |= 0x01<<(13+2*L) ;        // F +
       if((q&0x40)==0x40) RAM24[0] |= 0x01<<(13+2*L) ;        // G +
       if((q&0x80)==0x80) RAM24[0] |= 0x01<<(11-2*L) ;        // M 
}     
void LCD96map(void){
       int b ;                   
                  
           //  b = 0,1,2, 3,4,5, 6, 7, 8, 9,10,11, 12,13,14,15,16,17, 18,19,20,21,22,23
       char MAP[]={0,1,2, 7,8,9,10,11,12,13,14,15, 17,16,18,19,20,21, 24,25,26,27,28,29};
       // Bits     3,4,5,6,               22,23,            30,31 not used
              LCD->RAM[0*2]  = 0 ;
              LCD->RAM[1*2]  = 0 ;
              LCD->RAM[2*2]  = 0 ;
              LCD->RAM[3*2]  = 0 ;
              for(b=0;b<=23;b++){
                     LCD->RAM[0*2] |=  (RAM24[0]&(1<<b))<<(MAP[b]-b);
                     LCD->RAM[1*2] |=  (RAM24[1]&(1<<b))<<(MAP[b]-b);
                     LCD->RAM[2*2] |=  (RAM24[2]&(1<<b))<<(MAP[b]-b);
                     LCD->RAM[3*2] |=  (RAM24[3]&(1<<b))<<(MAP[b]-b);
              }
}
void N_LCD(long M){
       int t ;
      
       RAM24[0] = 0 ;
       RAM24[1] = 0 ;
       if( (M<=999999) && (M>=0) ) {
              t = 0 ;
              while(M>99999){
                     M = M - 100000 ;
                     t++ ;
              }
              map8to8(C8[t],5);
              t = 0 ;
              while(M>9999){
                     M = M - 10000 ;
                     t++ ;
              }
              map8to8(C8[t],4);         
              t = 0 ;
              while(M>999){
                     M = M - 1000 ;
                     t++ ;
              }
              map8to8(C8[t],3);
              t = 0 ;
              while(M>99){
                     M = M - 100 ;
                     t++ ;
              }
              map8to8(C8[t],2);
             
              t = 0 ;
              while(M>9){
                     M = M - 10 ;
                     t++ ;
              }
              map8to8(C8[t],1);         
              t = M ;
              map8to8(C8[t],0);         
              LCD96map();
              LCD->SR       |=     LCD_SR_UDR ;
              while( (LCD->SR&LCD_SR_UDD)==0 );
       }
       else{
              map8to8(0xC0,0);
              LCD96map();
              LCD->SR       |=     LCD_SR_UDR ;
              while( (LCD->SR&LCD_SR_UDD)==0 );
       }
}
void PAaft(char PIN, char FUNC){         // Port A alternate function
  GPIOA->MODER       &=  ~(0x03<<(2*PIN)) ;     // Clear Mode mask 
  GPIOA->MODER       |=    0x02<<(2*PIN)  ;     // 0=i; 1=O; 2=AltFun; 3=Analog  
  if(PIN<=7){
    GPIOA->AFR[0]    &=  ~(0x0F<<(4*PIN)) ;            // Clear AFR mask
    GPIOA->AFR[0]    |=    FUNC<<(4*PIN) ;             // Alt Func
      } else{
    GPIOA->AFR[1]    &=  ~(0x0F<<(4*(PIN-8))); // Clear AFR mask
    GPIOA->AFR[1]    |=    FUNC<<(4*(PIN-8)) ; // Alt Func
  } 
}                                
void PBaft(char PIN, char FUNC){         // Port B alternate function
  GPIOB->MODER       &=  ~(0x03<<(2*PIN)) ;     // Clear Mode mask 
  GPIOB->MODER       |=    0x02<<(2*PIN)  ;     // 0=i; 1=O; 2=AltFun; 3=Analog  
  if(PIN<=7){
    GPIOB->AFR[0]    &=  ~(0x0F<<(4*PIN)) ;            // Clear AFR mask
    GPIOB->AFR[0]    |=    FUNC<<(4*PIN) ;             // Alt Func
      } else{
    GPIOB->AFR[1]    &=  ~(0x0F<<(4*(PIN-8))); // Clear AFR mask
    GPIOB->AFR[1]    |=    FUNC<<(4*(PIN-8)) ; // Alt Func
  } 
}
void PCaft(char PIN, char FUNC){         // Port C alternate function
       GPIOC->MODER         &=  ~(0x03<<(2*PIN)) ;     // Clear Mode mask 
       GPIOC->MODER         |=    0x02<<(2*PIN) ;      // 0=i; 1=O; 2=AltFun; 3=Analog  
       if(PIN<=7){
              GPIOC->AFR[0] &=  ~(0x0F<<(4*PIN)) ;            // Clear AFR mask
              GPIOC->AFR[0]        |=    FUNC<<(4*PIN) ;             // Alt Func
              } else{
              GPIOC->AFR[1]        &=  ~(0x0F<<(4*(PIN-8))); // Clear AFR mask
              GPIOC->AFR[1]        |=    FUNC<<(4*(PIN-8)) ; // Alt Func
              } 
}
void LCD96conf(void){
       char i ;
       char Apins[]={1,2,3,8,9,10,15};          // 7 pins
       char Bpins[]={3,4,5,8,9,10,11,12,13,14,15};     // 11 pins
       char Cpins[]={0,1,2,3,6,7,8,9,10,11};           // 10 pins
       //  LCD on Board  Configuration
       RCC->AHBENR  |=  RCC_AHBENR_GPIOAEN ;  
       RCC->AHBENR   |=  RCC_AHBENR_GPIOBEN ;                
       RCC->AHBENR          |=  RCC_AHBENR_GPIOCEN ;                
       for(i=0;i<=6;i++) { PAaft(Apins[i],11);  }
       for(i=0;i<=10;i++){ PBaft(Bpins[i],11);  }
       for(i=0;i<=9;i++) { PCaft(Cpins[i],11);  }
       RCC->APB1ENR  |=  RCC_APB1ENR_LCDEN ;   
       LCD->CR              =      LCD_CR_MUX_SEG | 0x0C | 0x40 ;    // Duty=1/4 Bias=1/3  64-pin !
       LCD->FCR      =  0 ;                    // Reset condition
       LCD->FCR      |=     (4<<22) ;     // PS = 4  (Bits 22,23,24,25)
       LCD->FCR      |=     (1<<18) ;     // DIV = 1  (Bits 18,19,20,21)
       LCD->FCR      |=     (7<<10) ;     // CC = 7  (Bits 10,11,12)
       LCD->FCR      |=     (7<<4) ;      // PON = 7  (Bits 4,5,6)
       LCD->CR              |=     LCD_CR_LCDEN ;
       while( (LCD->SR&LCD_SR_RDY)==0 ); // Wait till ready
       RAM24[0] = 0 ;
       RAM24[1] = 0 ;
       RAM24[2] = 0 ;
       RAM24[3] = 0 ;
}
void UserInit(void){
       //  Enable LSI for LCD                                                                                           
       RCC->APB1ENR  |=     RCC_APB1ENR_PWREN ;
       PWR->CR                    |=     PWR_CR_DBP ;
       RCC->CSR             |=     RCC_CSR_LSION ;
       while( (RCC->CSR&RCC_CSR_LSIRDY)==0 );   // Wait till LSE Ready    
       RCC->CSR             &=     ~RCC_CSR_RTCSEL      ;                          // Mask
       RCC->CSR             |=     RCC_CSR_RTCSEL_LSI  ;     
      
       LCD96conf();
      
       //  MSI 
  RCC->CR     |=      RCC_CR_MSION ;
  while( (RCC->CR&RCC_CR_MSIRDY)==0 );                        // Wait till MSI Ready
       RCC->ICSCR    =  (RCC->ICSCR&(~RCC_ICSCR_MSIRANGE)) | RCC_ICSCR_MSIRANGE_6 ;       // 000--> 110
  RCC->CFGR   &=     ~RCC_CFGR_SW ;                           // Clock Switch Mask
  RCC->CFGR   |=     RCC_CFGR_SW_MSI ;                        // Switch to MSI
  while( (RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_MSI );        // Wait till MSI
       //  Core Voltage
  RCC->APB1ENR  |=  RCC_APB1ENR_PWREN ;
  while( (PWR->CSR&PWR_CSR_VOSF)!=0 ) ; // Wait till '0'
  //  PWR->CR &= ~PWR_CR_VOS ;          // This is forbidden
  //  PWR->CR |=  PWR_CR_VOS_0 ;        // Then this does not work
  PWR->CR = (PWR->CR&(~PWR_CR_VOS)) | PWR_CR_VOS_0 ;    // 10->00->01
  while( (PWR->CSR&PWR_CSR_VOSF)!=0 ) ; // Wait till '0' again
       //  WS=1 
  FLASH->ACR    |=     FLASH_ACR_ACC64 ;           // 64-bit access
  while( (FLASH->ACR&FLASH_ACR_ACC64)==0) ;
  FLASH->ACR    |=     FLASH_ACR_PRFTEN ;         // Prefetch
  FLASH->ACR    |=     FLASH_ACR_LATENCY ;        // 1 wait state
  while( (FLASH->ACR&FLASH_ACR_LATENCY)==0) ;                 // Wait till 1 WS
  //  HSI 
  RCC->CR     |=      RCC_CR_HSION ;
  while( (RCC->CR&RCC_CR_HSIRDY)==0 );                        // Wait till HSI Ready
  RCC->CFGR   &=     ~RCC_CFGR_SW ;                           // Clock Switch Mask
  RCC->CFGR   |=     RCC_CFGR_SW_HSI ;                        // Switch to HSI
  while( (RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_HSI );        // Wait till HSI
       // PLL
  RCC->CR   &=       ~RCC_CR_PLLON ;                          // Off PLL
       while( (RCC->CR&RCC_CR_PLLRDY)!=0 );     // Wait till PLL Clear
       RCC->CFGR     &=     ~RCC_CFGR_PLLMUL ;       // Mask  
       RCC->CFGR     |=  RCC_CFGR_PLLMUL4 ;                   // multiply
       RCC->CFGR      =  (RCC->CFGR&(~RCC_CFGR_PLLDIV)) | RCC_CFGR_PLLDIV2 ;       // divide
       RCC->CFGR     &=  ~RCC_CFGR_PLLSRC ;                   // Mask
       RCC->CFGR     |=  RCC_CFGR_PLLSRC_HSI ;         //
       RCC->CR   |=  RCC_CR_PLLON ;
       while( (RCC->CR&RCC_CR_PLLRDY)==0 );  // Wait till PLL Ready
       RCC->CFGR &=  ~RCC_CFGR_SW ;          // Clock Switch Mask
  RCC->CFGR |=   RCC_CFGR_SW_PLL ;      // Switch to PLL
  while( (RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_PLL ); // Wait till PLL
       //  Timer9  Configuration
       RCC->APB2ENR  |=  RCC_APB2ENR_TIM9EN ; 
       TIM9->PSC = 32000 - 1 ;            // --> 1 kHz
       TIM9->ARR = 1000 - 1 ;             // --> 1 s
       TIM9->CR1     |= TIM_CR1_CEN ;     // Enable Timer
       TIM9->SR      &= ~TIM_SR_UIF;      // Clear Timer Flag
       TIM9->DIER    |= TIM_DIER_UIE ;    // Enable Timer Interrupt
}
That is all for the time being.

1 comment:

  1. can you please explain the above code
    thanks
    k.arif4@hotmail.com

    ReplyDelete