Monday, 17 July 2017

STM32F103C8T6

20170727.4

Items:
1  PC    (Windows 7)
2  Internet access
3  ST-Link V2    US$ 2.57         
4  STM32F103C8T6 Minimum System Development Board    US$ 2.15    

5  IDE    (Keil MDK523)
6  Breadboard, connectors, LEDs, resistors etc
7  74HC164
8  LCD 1602

Setup:
Read STM32F103xx Reference Manual
Read STM32F103x8 Datasheet
Download The-Generic-STM32F103-Pinout-Diagram
Install IDE including the STM32F100 pack and the ST-Link V2 driver
Connect the STM32F103 to the ST-LinkV2
Plug the ST-LinkV2 to the PC

Programming:
Launch the IDE
Create a new uVision project with STM32F103C8 as the device,
     and include the CMSIS CORE and the Device Startup.
In "Options for Target", use ST-Link Debugger with 'SW' setting.
Type in a program, name it main.c and add it to the project
Rebuild and (Click Start/Stop) Debug (Session)
(Click) Run and check that the STM32F103 behaves as in the program.    

Approach:
IDE usage and downloading
Simple output
Interrupt
SPI output
Clock and timing
LCD 1602  next...

Notes on the Examples:
T10.c          Just to test program compilation and downloading.
T11.c          Turn on the LED on the board.
T15.c          Blink the LED.
T16.c          Brightness control, just for fun. Not useful.
T21.c          Test interrupt programming.
T32.c          SPI1 Output to 74HC164
T40.c          Check clock source
T42.c          Select HSI, 1-second interval
T43.c          HSI with PLL --> 16 MHz
T44.c          HSI with PLL --> 64 MHz
T46.c          Select HSE (8-MHz)
T47.c          HSE with PLL --> 72 MHz

Examples:
==========
//  T10.c

int main(void){

    while(1);
}

==========
//  T11.c

#include <stm32f10x.h>

int main(void){

    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

    while(1){}
}

==========
//  T15.c

#include <stm32f10x.h>

int main(void){
    int i,j ;
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

    while(1){
        GPIOC->ODR    &=     ~(1<<13) ;  
        for(i=0;i<=1000;i++){for(j=0;j<=1000;j++);}  // Software delay
        GPIOC->ODR    |=     (1<<13) ;  
        for(i=0;i<=1000;i++){for(j=0;j<=1000;j++);}  // Software delay
    }
   
    //while(1){}
}

==========
//  T16.c

#include <stm32f10x.h>

int main(void){
    int i,j ;
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

    while(1){
    for(j=10;j<4990;j++){
            GPIOC->ODR    &=     ~(1<<13) ;
            for(i=0;i<j;i++);         // ON delay
            GPIOC->ODR    |=     (1<<13) ;  
            for(i=0;i<(5000-j);i++);  // Off delay
        }
    }
   
    //while(1){}
}

==========
//  T21.c

#include <stm32f10x.h>

int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 999 ;                            // 1000
  //TIM2->ARR = 999 ;                    
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
   
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
    i++ ;
    if(i<=4)GPIOC->ODR    &=     ~(1<<13) ;
        else  GPIOC->ODR    |=     (1<<13) ;  
    if(i>5) i = 0 ;
}

==========
//  T32.c

#include <stm32f10x.h>

int main(void){
    int i,j,k ;
  
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;  
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float  
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
  
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1  
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something
    k = 0 ;
    while(1){
    //    for(i=0;i<=1000;i++){for(j=0;j<=10000;j++);}  // Software delay
    //    while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
    //    SPI1->DR = k ;                                          
    //    k++ ;
    }      
}

==========
//  T40.c    Check clock source

#include <stm32f10x.h>
int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1 
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;    
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
   
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1   
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something

    i = RCC->CFGR ;
    while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i&0xFF ;                                   
    while(1) ;

//  Timer 2
    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 7999 ;                        // 8000   1 ms
  TIM2->ARR = 999 ;                            // 1000   1 s
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i ;                                       
    i++ ;
    if(i==200) i = 0 ;                                            // 0 to 199
}

==========

//  T42.c    HSI 8-MHz

#include <stm32f10x.h>
int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1 
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;    
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
   
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1   
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something

    RCC->CR             |=      RCC_CR_HSION ;                // Turn on HSI 
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask                                                                                    
                                                                                    // Use HSI
    while( (RCC->CR&RCC_CR_HSIRDY)==0 );        // Wait till HSI ready
    while( (RCC->CFGR&RCC_CFGR_SWS)!=0 );        // Wait till HSI used                   
   
//  Timer 2
    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 7999 ;                        // 8000   1 ms
  TIM2->ARR = 999 ;                            // 1000   1 s
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i ;                                       
    i++ ;
    if(i==200) i = 0 ;                                            // 0 to 199
}

==========
//  T43.c    HSI 8-MHz PLL x4

#include <stm32f10x.h>
int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1 
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;    
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
   
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1   
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something

    RCC->CR             |=      RCC_CR_HSION ;                // Turn on HSI 
    while( (RCC->CR&RCC_CR_HSIRDY)==0 );        // Wait till HSI ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask                                                                                    
                                                                                    // Use HSI
    while( (RCC->CFGR&RCC_CFGR_SWS)!=0 );        // Wait till HSI used               
    RCC->CR             &=     ~RCC_CR_PLLON ;                // Turn off PLL   
    RCC->CFGR            &=     ~RCC_CFGR_PLLMULL ;        // Mask    
    RCC->CFGR            |=      RCC_CFGR_PLLMULL_1 ;    // x4
    RCC->CFGR            &=     ~RCC_CFGR_PLLSRC ;        // Mask
                                                                                    // Use HSI /2
    RCC->CR             |=      RCC_CR_PLLON ;                // Turn on PLL
    while( (RCC->CR&RCC_CR_PLLRDY)==0 );        // Wait till PLL ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask        
    RCC->CFGR            |=      RCC_CFGR_SW_PLL ;        // Use PLL                           
    while( (RCC->CFGR&RCC_CFGR_SWS_PLL)==0 );        // Wait till PLL used               

   
//  Timer 2
    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 7999 ;                        // 8000   1 ms
  TIM2->ARR = 999 ;                            // 1000   1 s
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i ;                                       
    i++ ;
    if(i==200) i = 0 ;                                            // 0 to 199
}

==========
//  T44.c    HSI 8-MHz /2 PLL x16    64 MHz  

#include <stm32f10x.h>
int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1 
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;    
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
   
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1   
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something

    RCC->CR             |=      RCC_CR_HSION ;                // Turn on HSI 
    while( (RCC->CR&RCC_CR_HSIRDY)==0 );        // Wait till HSI ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask                                                                                    
                                                                                    // Use HSI
    while( (RCC->CFGR&RCC_CFGR_SWS)!=0 );        // Wait till HSI used               
    RCC->CR             &=     ~RCC_CR_PLLON ;                // Turn off PLL   
    RCC->CFGR            &=     ~RCC_CFGR_PLLMULL ;        // Mask    
    RCC->CFGR            |=      RCC_CFGR_PLLMULL ;        // x16
    RCC->CFGR            &=     ~RCC_CFGR_PLLSRC ;        // Mask
                                                                                    // Use HSI /2
    RCC->CR             |=      RCC_CR_PLLON ;                // Turn on PLL
    while( (RCC->CR&RCC_CR_PLLRDY)==0 );        // Wait till PLL ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask        
    RCC->CFGR            |=      RCC_CFGR_SW_PLL ;        // Use PLL                           
    while( (RCC->CFGR&RCC_CFGR_SWS_PLL)==0 );        // Wait till PLL used               

   
//  Timer 2
    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 7999 ;                        // 64000000 / 8000   8 kHz
  TIM2->ARR = 7999 ;                        // 8000 / 8000    1 s
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i ;                                       
    i++ ;
    if(i==200) i = 0 ;                                            // 0 to 199
}

==========
//  T46.c    Select HSE

#include <stm32f10x.h>
int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1 
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;    
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
   
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1   
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something

    RCC->CR             &=     ~RCC_CR_HSEBYP ;            // HSE not bypassed
    RCC->CR             |=      RCC_CR_HSEON ;                // Turn on HSE
    while( (RCC->CR&RCC_CR_HSERDY)==0 );        // Wait till HSE ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask                                                                                    
    RCC->CFGR            |=      RCC_CFGR_SW_HSE ;        // Use HSE
    while( (RCC->CFGR&RCC_CFGR_SWS_HSE)!=RCC_CFGR_SWS_HSE );        // Wait till HSE used                                                                   

//  Timer 2
    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 7999 ;                        // 8000   1 ms
  TIM2->ARR = 999 ;                            // 1000   1 s
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i ;                                       
    i++ ;
    if(i==200) i = 0 ;                                            // 0 to 199
}

==========
//  T47.c    HSE with PLL x9    72 MHz

#include <stm32f10x.h>
int i ;

int main(void){
   
    RCC->APB2ENR    |=         RCC_APB2ENR_IOPCEN ;   
    GPIOC->CRH         &=            ~GPIO_CRH_MODE13 ;        // Mask
    GPIOC->CRH         &=            ~GPIO_CRH_CNF13 ;            // Mask
  GPIOC->CRH         |=         GPIO_CRH_MODE13_1 ;  // 00 10 PushPull Output 2 MHz
  GPIOC->ODR    &=         ~(1<<13) ;               // Clear bit 13  LED on.

//  SPI1 
  RCC->APB2ENR    |=         RCC_APB2ENR_IOPAEN ;    
    GPIOA->CRL         &=            ~GPIO_CRL_MODE5 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF5  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE5_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF5_1 ;        // Sck (Alt Ftn)  Pushpull
    GPIOA->CRL         &=            ~GPIO_CRL_MODE6 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF6  ;            // Mask
    // GPIOA->CRL                                                           // Input
    // GPIOA->CRL                                                             // MISO float   
    GPIOA->CRL         &=            ~GPIO_CRL_MODE7 ;            // Mask
    GPIOA->CRL         &=            ~GPIO_CRL_CNF7  ;            // Mask
    GPIOA->CRL         |=         GPIO_CRL_MODE7_1 ;      // Output 2 MHz
    GPIOA->CRL         |=              GPIO_CRL_CNF7_1 ;        // MOSI (Alt Ftn)  Pushpull
   
  RCC->APB2ENR  |=          RCC_APB2ENR_SPI1EN ;
    SPI1->CR1            |=    SPI_CR1_BR ;                    // f/256
    SPI1->CR1            &=    ~SPI_CR1_DFF ;                // 8-bit
    SPI1->CR1            &=    ~SPI_CR1_CPOL ;                // POL=0
    SPI1->CR1            &=    ~SPI_CR1_CPHA ;                // Rising edge
    SPI1->CR1            &=    ~SPI_CR1_LSBFIRST ;        // MSB first
    SPI1->CR1            |=    SPI_CR1_SSM ;                    // SSM=1   
    SPI1->CR1            |=    SPI_CR1_SSI;                    // SSI=1
  SPI1->CR1     |=  SPI_CR1_MSTR ;                 // Master
    SPI1->CR1     |=  SPI_CR1_SPE ;                 // Enable SPI
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = 0x53 ;                                        // Just show something

    RCC->CR             &=     ~RCC_CR_HSEBYP ;            // HSE not bypassed
    RCC->CR             |=      RCC_CR_HSEON ;                // Turn on HSE
    while( (RCC->CR&RCC_CR_HSERDY)==0 );        // Wait till HSE ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask                                                                                    
    RCC->CFGR            |=      RCC_CFGR_SW_HSE ;        // Use HSE
    while( (RCC->CFGR&RCC_CFGR_SWS_HSE)!=RCC_CFGR_SWS_HSE );        // Wait till HSE used                                                                   

    RCC->CR             &=     ~RCC_CR_PLLON ;                // Turn off PLL   
    RCC->CFGR            &=     ~RCC_CFGR_PLLMULL ;        // Mask    
    RCC->CFGR            |=      RCC_CFGR_PLLMULL_2 ;   
    RCC->CFGR            |=      RCC_CFGR_PLLMULL_1 ;   
    RCC->CFGR            |=      RCC_CFGR_PLLMULL_0 ;    // x9
    RCC->CFGR            &=     ~RCC_CFGR_PLLXTPRE ;    // HSE not /2
    RCC->CFGR            |=      RCC_CFGR_PLLSRC ;        // Use HSE
    RCC->CR             |=      RCC_CR_PLLON ;                // Turn on PLL
    while( (RCC->CR&RCC_CR_PLLRDY)==0 );        // Wait till PLL ready
    RCC->CFGR            &=     ~RCC_CFGR_SW ;                // Mask        
    RCC->CFGR            |=      RCC_CFGR_SW_PLL ;        // Use PLL                           
    while( (RCC->CFGR&RCC_CFGR_SWS_PLL)==0 );        // Wait till PLL used               

//  Timer 2
    RCC->APB1ENR    |=     RCC_APB1ENR_TIM2EN ;
    TIM2->PSC = 8999 ;                        // 72 MHz / 9k = 8k
  TIM2->ARR = 7999 ;                        // 8k/8000   1 s
  TIM2->CR1     |= TIM_CR1_CEN ;                 // Enable Timer
  TIM2->SR      &= ~TIM_SR_UIF;           // Clear Timer Flag
  TIM2->DIER    |= TIM_DIER_UIE ;                // Enable Timer Interrupt

    NVIC->ISER[0]    |= 1<<TIM2_IRQn ;                
   
    i = 0 ;
    while(1){}        // Wait for interrupt
}
void TIM2_IRQHandler(void){
    TIM2->SR             &= ~TIM_SR_UIF;                // Clear Timer Flag
  while((SPI1->SR&SPI_SR_TXE)==0);                 // Wait till transmitter empty
  SPI1->DR = i ;                                       
    i++ ;
    if(i==200) i = 0 ;                                            // 0 to 199
}

==========

==========



 

No comments:

Post a Comment