MCBSTM32C/Blinky simple with clock control

From Teknologisk videncenter
Jump to: navigation, search

This article is an expansion of Blinky_simple See |RCC for further information.

Additional references in "minimum gpio.h"

Add the following to "minumum gpio.h"

//AFIO
#define AFIO_BASE             (APB2PERIPH_BASE + 0x0000)
#define AFIO                  ((AFIO_TypeDef   *) AFIO_BASE    )
typedef struct
{
  __IO uint32_t EVCR;
  __IO uint32_t MAPR;
  __IO uint32_t EXTICR[4];
} AFIO_TypeDef;

#define AFIO                  ((AFIO_TypeDef   *) AFIO_BASE    )


//FLASH
#define FLASH                 ((FLASH_TypeDef  *) FLASH_BASE   )
#define FLASH_BASE            (AHBPERIPH_BASE  + 0x2000)
typedef struct
{
  __IO uint32_t ACR;
  __IO uint32_t KEYR;
  __IO uint32_t OPTKEYR;
  __IO uint32_t SR;
  __IO uint32_t CR;
  __IO uint32_t AR;
  __IO uint32_t RESERVED;
  __IO uint32_t OBR;
  __IO uint32_t WRPR;
} FLASH_TypeDef;
#define FLASH                 ((FLASH_TypeDef  *) FLASH_BASE   )

Add rcc.c

#include "minimum gpio.h"
//HeTh@mercantec 2011
/***************** useful RCC_CR bits ****************************/
#define RCC_CR_HSION       (0x00000001)              /* Internal High Speed clock enable     */
#define RCC_CR_HSIRDY      (0x00000002)              /* Internal High Speed clock ready flag */
#define RCC_CR_HSEON       (0x00010000)              /* External High Speed clock enable     */
#define RCC_CR_HSERDY      (0x00020000)              /* External High Speed clock ready flag */
#define RCC_CR_PLL1ON      (0x01000000)              /* PLL1 enable                          */
#define RCC_CR_PLL1RDY     (0x02000000)              /* PLL1 clock ready flag                */
#define RCC_CR_PLL2ON      (0x04000000)              /* PLL2 enable                          */
#define RCC_CR_PLL2RDY     (0x08000000)              /* PLL2 clock ready flag                */
#define RCC_CR_PLL3ON      (0x10000000)              /* PLL3 enable                          */
#define RCC_CR_PLL3RDY     (0x20000000)              /* PLL3 clock ready flag                */

/***************** useful RCC_CFGR bits **************************/
#define RCC_CFGR_HSION       (0x00000000)           /* Internal High Speed clock selected   */
#define RCC_CFGR_HSEON       (0x00000001)           /* External High Speed clock selected   */
#define RCC_CFGR_PLLON       (0x00000002)           /* PLL Speed clock selected             */
#define RCC_CFGR_PLLSRC      (0x00010000)			 /* PLLSRC PREDIV selected				 */


/* sub rcc_apb2enr()
   abstract: ¨Select preconfigured System Clock Rates using the PLL

   input...:  mask     : Setting/resetting bitmask to RCC_APB2ENR (Section 8.3.7)

   			 enable=0 : Disable clocks in bitmask
   			 enable=1 : Enable clocks in bitmask
			 
   output..: 0
   limits..: No errorcheck performed
*/
void rcc_apb2enr(  int mask,int enable) {
	if ( enable ) {
		RCC->APB2ENR |= mask;
	} else {
		RCC->APB2ENR &= ~mask;
	}
}

void rcc_apb1enr(  int mask,int enable) {
	if ( enable ) {
		RCC->APB1ENR |= mask;
	} else {
		RCC->APB1ENR &= ~mask;
	}
}

void rcc_cfgr(  int mask,int enable) {
	if ( enable ) {
		RCC->CFGR |= mask;
	} else {
		RCC->CFGR &= ~mask;
	}
}
/** AFIO **/
void rcc_afio_mapr(  int mask,int enable) {
	if ( enable ) {
		AFIO->MAPR |= mask;
	} else {
		AFIO->MAPR &= ~mask;
	}
}
/********************** S Y S C L K    M O D E S - PREDIV1 PLLMUL ******************
 MODE.........: The mode to select in the call to rss_set_sysclk
 SYSCLK.......: The System Clock Clocks the fx. AHB Prescaler
 FCLK/HCLK....: HCLK = Processor Clock (Clocks the Cortex M3) FCLK = Free Running Processor Clock
 SOURCE.......: clock Source. Selected with the SW[1:0]  bits
 SW[1:0]......: RCC_CFGR section 8.3.2 - System Clock Switch (HSI,HSE,PLL)
 PREDIV1SRC...: RCC_CFGR2 section 8.3.12 - PREDIV1 entry Clock Source (HSE or PLL2)
 PREDIV1[3:0].: RCC_CFGR2 section 8.3.12 - PREDIV1 division factor (Divide by 1 to 16)
 PLLSRC.......: RCC_CFGR section 8.3.2 - PLLMUL source HSI or HSE
 PLLMUL[3:0]..: RCC_CFGR section 8.3.2 - PLLMUL multiplication factor (4 to 9 and 6.5)
 HPRE[3:0]....: RCC_CFGR section 8.3.2 - AHB prescaler (Division factor 2,4,8...512)
 CSS..........:	RCC_CR section 8.3.1 - Clock Security System On/Off
 HSION........:	RCC_CR section 8.3.1 - High Speed Internal oscilator On/Off (Check HSIRDY)
 HSEON........:	RCC_CR section 8.3.1 - High Speed External oscilator On/Off (Check HSERDY)
 HSEBYP.......: RCC_CR section 8.3.1 - HSE oscilator or oscilator bypass.
 LATENCY[2:0].: FLASH_ACR section 3.3 - Flash Wait States (0 to 2)
 PRFTBE.......: FLASH_ACR section 3.3 - Flash Prefetch Buffer enable
 OTGFSPRE.....: RCC_CFGR section 8.3.2 - USB OTG FS Prescaler (divide by 2 or 3) SYSCLK (72 or 48 Mhz)
 
********************** S Y S C L K    M O D E S - PREDIV2 PLLMUL2 PREDIV1 PLLMUL******************
 MODE.........: The mode to select in the call to rss_set_sysclk
 SYSCLK.......: The System Clock Clocks the fx. AHB Prescaler
 FCLK/HCLK....: HCLK = Processor Clock (Clocks the Cortex M3) FCLK = Free Running Processor Clock
 SOURCE.......: clock Source. Selected with the SW[1:0]  bits
 SW[1:0]......: RCC_CFGR section 8.3.2 - System Clock Switch (HSI,HSE,PLL)
 PREDIV1SRC...: RCC_CFGR2 section 8.3.12 - PREDIV1 entry Clock Source (HSE or PLL2)
 PREDIV1[3:0].: RCC_CFGR2 section 8.3.12 - PREDIV1 division factor (Divide by 1 to 16)
 PLLSRC.......: RCC_CFGR section 8.3.2 - PLLMUL source HSI or HSE
 PLLMUL[3:0]..: RCC_CFGR section 8.3.2 - PLLMUL multiplication factor (4 to 9 and 6.5)
 HPRE[3:0]....: RCC_CFGR section 8.3.2 - AHB prescaler (Division factor 2,4,8...512)
 CSS..........:	RCC_CR section 8.3.1 - Clock Security System On/Off
 HSION........:	RCC_CR section 8.3.1 - High Speed Internal oscilator On/Off (Check HSIRDY)
 HSEON........:	RCC_CR section 8.3.1 - High Speed External oscilator On/Off (Check HSERDY)
 HSEBYP.......: RCC_CR section 8.3.1 - HSE oscilator or oscilator bypass.
 LATENCY[2:0].: FLASH_ACR section 3.3 - Flash Wait States (0 to 2)
 PRFTBE.......: FLASH_ACR section 3.3 - Flash Prefetch Buffer enable
 OTGFSPRE.....: RCC_CFGR section 8.3.2 - USB OTG FS Prescaler (divide by 2 or 3) SYSCLK (72 or 48 Mhz)

  MODE  SYSCLK  FCLK/HCLK SOURCE  SW[1:0] PREDIV1SRC PREDIV1[3:0] PLLSRC PLLMUL[3:0] HPRE[3:0] CSS HSI HSE LATENCY[2:0] PRFTBE        
    1	36 MHz	  36 Mhz    HSI     00

   SYSCLK er Sytem Clk : FCLK Cortex Free Running Clock
   1   36 MHz    HSI     00
   2   24 MHz    HSI     00
   3   16 MHz    HSI     00
   4    8 MHz    HSI     00
   5	4 MHz    HSI     00
   6	2 MHz    HSI     00
   7	1 MHz    HSI     00
   8  500 KHz    HSI     00
   9  125 KHz    HSI     00
*******************************************************************
See http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS/Clock_Paths
for clock_modes.
*********************
clock_mode 1:
=============
Oscilator: HSI = 8 Mhz 
USB......: Not possible. No path.
SYSCLK...: 8 Mhz
HCLK/FCLK: 8 Mhz / [1,2,4,8...512] = 8 Mhz, 4 Mhz, 2 Mhz ...	15,625 Khz

clock_mode 2:
=============
Oscilator: HSI = 8 Mhz
USB......: Not possible. 48 Mhz required (Higest possible = 18 Mhz)
SYSCLK...: Through PLLMUL from 4 Mhz to 36 Mhz
HCLK/FCLK: SYSCLK / [1,2,4,8...512] (Highest 36 Mhz)

clock_mode 3:
=============
Oscilator: HSE (25 MHz crystal onboard)
USB......: Not possible. No path.
SYSCLK...: 25 Mhz
HCLK/FCLK: SYSCLK / [1,2,4,8...512] (Highest 25 Mhz)

clock_mode 4:
=============
Oscilator: HSE (25 MHz crystal onboard)
USB......: Not possible. 48 Mhz required 
SYSCLK...: SYSCLK <= 72 Mhz highest possible (/2*5=62,5Mhz)
HCLK/FCLK: SYSCLK / [1,2,4,8...512] (Highest 62,5 Mhz)

clock_mode 5:
=============
Oscilator: HSE (25 MHz crystal onboard)
USB......: Possible (25/5*8/5*9 and /3)
SYSCLK...: SYSCLK = 72 MHz
HCLK/FCLK: SYSCLK / [1,2,4,8...512] (Highest 72 MHz)

*******************************************************************
                 C L O C K    S T A R T U P
*******************************************************************

After Reset the controller uses the HSI - High Speed Internal Clock
The HSI runs at appor. 8 Mhz - See RCC_RC register (Section 8.3.1)

The HSI is at Reset selected as System Clock 
    - RCC_CFGR bits SW[1:0] = 00

******** Setting the Clock to HSE  - High Speed External **********

The External Clock Signal og Crystal can be selected as base for
System clock throgh RCC_CFGR bits SW[1:0]
                SW[1:0] = 00 - HSI  (Speed: ~8 Mhz)
				SW[1:0]	= 01 - HSE  (Speed: Depend on Crystal)
				SW[1:0] = 10 - PLL  (Speed dependent on HSI or HSE
				                     and setting of prescaler and
									 PLL multiplication factor)
******************************************************************/


/******************** HSE as System Clock *************************
To use she HSE as System Clock the following sequence is necessary
  1: Selecting External Oscillator or External Clock (Section 8.2.1)
     Setting RCC_CR bit HSEBYP = 0 selects oscillator using Crystal
	                    HSEBYP = 1 selects external clock
     The HSEBYP can only be written when RCC_CR bit HSEON = 0
 
  2: Enabling the HSE clock - RCC_CR bit
  		HSEON = 0 HSE : oscillator off
        HSEON = 1 HSE : oscillator on

  3: Waiting until HSE clock is ready an can be used as Clock Source 
        RCC_CR bit HSERDY = 0 : Oscillator Not Ready
		RCC_CR bit HSERDY = 1 : Oscillator Ready

  4: When HSERDY = 1 select HSE as Clock Source
        RCC_CFGR bits SW[1:0] = 01 : HSE selected
******************************************************************/


//HUSK SLÅ UBRUGT PLL FRA
void rcc_clockmode3(void) {
	int i;
	
	//Step 1 - HSEBYP default = 0

	//Step 2
	RCC->CR |= RCC_CR_HSEON;  // HSEON=1
	
	//Step 3
	while ((RCC->CR & RCC_CR_HSERDY) == 0) {}; // Wait HSERDY = 1
	for (i=0; i <100; i++); //Wait for Clock to stabilize before changing

	//Step 4
	RCC->CFGR |= RCC_CFGR_HSEON;
}

/******************** PLL as System Clock *************************
To use she PLL as System Clock the following sequence is necessary
 NOTE: The HSI Clock can be used as source for PLL Clocking, but
       it's not possible in this program to select. This program will
	   default to using the HSE with a crystal.


  1: Selecting External Oscillator or External Clock (Section 8.2.1)
     Setting RCC_CR bit HSEBYP = 0 selects oscillator using Crystal
	                    HSEBYP = 1 selects external clock
     The HSEBYP can only be written when RCC_CR bit HSEON = 0
 
  2: Enabling the HSE clock - RCC_CR bit
  		HSEON = 0 HSE : oscillator off
        HSEON = 1 HSE : oscillator on

  3: Waiting until HSE clock is ready an can be used as Clock Source 
        RCC_CR bit HSERDY = 0 : Oscillator Not Ready
		RCC_CR bit HSERDY = 1 : Oscillator Ready

  4: Select Prescaler clock Source RCC_CFGR2 bit PREDIV1SRC
  		PREDIV1SRC = 0 : HSE Clock selected (Ddefault)
		PREDIV1SRC = 1 : PLL3 VCO clock selected

  5: Select the Prescaler division factor. (Section 8.3.12)
     RCC_CFGR2 bits PREDIV1[3:0]
	    PREDIV1[3:0] = 0000: input clock not divided
		PREDIV1[3:0] = 0001: input clock divided by 2
		PREDIV1[3:0] = 0010: input clock divided by 3
		PREDIV1[3:0] = 0011: input clock divided by 4
		PREDIV1[3:0] = 0100: input clock divided by 5
		PREDIV1[3:0] = 0101: input clock divided by 6
		PREDIV1[3:0] = 0110: input clock divided by 7
		PREDIV1[3:0] = 0111: input clock divided by 8
		PREDIV1[3:0] = 1000: input clock divided by 9
		PREDIV1[3:0] = 1001: input clock divided by 10
		PREDIV1[3:0] = 1010: input clock divided by 11
		PREDIV1[3:0] = 1011: input clock divided by 12
		PREDIV1[3:0] = 1100: input clock divided by 13
		PREDIV1[3:0] = 1101: input clock divided by 14
		PREDIV1[3:0] = 1110: input clock divided by 15
		PREDIV1[3:0] = 1111: input clock divided by 16

  6: Select the PLL Source HSI or PREDIV (Section 8.3.2)
  		PLLSRC = 0 HSI oscillator clock / 2 selected
		PLLSRC = 1 Clock from PREDIV selected

  7: Select the PLL multiplication factor RCC_CFGR bits PLLMUL[3:0]
     (Section 8.3.2)
     NOTE: These bits can only be written when PLL is disabled
	    PLLMUL[3:0] = 0010 PLL input Clock X 4
		PLLMUL[3:0] = 0011 PLL input Clock X 5
		PLLMUL[3:0] = 0100 PLL input Clock X 6
		PLLMUL[3:0] = 0101 PLL input Clock X 7
		PLLMUL[3:0] = 0110 PLL input Clock X 8
		PLLMUL[3:0] = 0111 PLL input Clock X 9
		PLLMUL[3:0] = 1101 PLL input Clock X 6.5
	 CAUTION: The PLL output frequency must not exceed 72 MHz

  8: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] (section 3.3) 
  		LATECY[2:0] = 000 - Zero wait state. ( 0 Hz  < SYSCLK <= 24 Mhz)
  		LATECY[2:0] = 001 - One wait state.  (24 MHz < SYSCLK <= 48 Mhz)
  		LATECY[2:0] = 010 - Two wait state.  (48 MHz < SYSCLK <= 72 Mhz)
  
  9: Enable PLL - RCC_CR bit PLLON 1=Enable

  10: Wait for PLL to stabilize - RCC_CR bit PLLRDY  1=Ready

  11: Select PLL as Clock Source	(Section 8.3.2)
        RCC_CFGR bits SW[1:0] = 10 : PLL selected

  12: Turn of HSI to reduce power consumption
******************************************************************
EXAMPLE:
        Crystal = 25 Mhz
		PREDIV[3:0] = 0100 : Division factor 5
		PLLMUL[3:0] = 0111 : Multiply by 9

		System Clock = 25 Mhz / 5 * 9 = 45 Mhz
*****************************************************************/

/* sub rss_clockmode4()
   abstract: Select preconfigured System Clock Rates using the PLL

   input...: rate = Preconfigured rate
         		Crystal: 25 Mhz
		 		rate = 0 gives clock rate 66,667 Mhz
		      		Clock Rate = 25 Mhz / 3 * 8 = 66,667 Mhz
		 		rate = 1 gives clock rate 45,000 Mhz
		 	  		Clock Rate = 25 Mhz / 5 * 9 = 45,000 Mhz
   output..: 0 = New System Clock started
             >0 = Error - Old system clock still used
			  1 = Invalid Clock Rate
   limits..: No check performed if HSE already System Clock
*/

/*
Clk control with 6 modes and shift between them

*/
int rcc_clockmode4( int rate ) {
	#define RATES 3
	// Array of clockmodes 45,66.667 Mhz
	int prediv[RATES] = {0x4,0x5,0xf}; // PREDIV 3 and PREDIV 5 values
	int pllmul[RATES] = {0x6 << 18,0x7 << 18,0x2 << 18}; // PLLMUL 8 and PLLMUL 9 values
	int flshws[RATES] = {0x1,0x2,0x0}; // Flash Latency 1 wait state and 2 wait states
	int i;
	 
	if ( rate >= RATES ) { // Check if valid Clock Rate
		return(1);
	}
	// Step 1 - HSEBYP default = 0
	 
	// Step 2 - Enabling the HSE clock
 	RCC->CR |= RCC_CR_HSEON;  // HSEON=1
	
	//Step 3 - Waiting until HSE clock is ready
	while ((RCC->CR & RCC_CR_HSERDY) == 0) {}; // Wait HSERDY = 1

   //Step 4 - Select Prescaler clock Source (Default OK)

   //Step 5	- Select the Prescaler division factor.
   RCC->CFGR2 |= prediv[rate];

   //Step 6	- Select PREDIV as source for PLL
   RCC->CFGR |= RCC_CFGR_PLLSRC;


   //Step 7	- Select the PLL multiplication factor
   RCC->CFGR |= pllmul[rate];

   //Step 8	- Select Flash wait states
   FLASH->ACR |= flshws[rate];

   //Step 9	- Enable PLL
   RCC->CR |= RCC_CR_PLL1ON;

   //Step 10 - Waiting until PLL clock is ready
	while ((RCC->CR & RCC_CR_PLL1RDY) == 0) {}; // Wait HSERDY = 1
	for (i=0; i <100; i++); //Wait for Clock to stabilize before changing

   //Step 11 - select PLL as Clock Source
	RCC->CFGR |= RCC_CFGR_PLLON;

   //Step 12 - Disable HSI
	RCC->CR &= !RCC_CR_HSION;
	return(0);
}

/* sub rcc_clockmode1()
   abstract: Select default as System Clock (HSI 8 Mhz)

   input...:  -

   output..: -
   limits..: No errorcheck performed
   *********************************************
   See: http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS/Clock_Paths
        http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS
   *********************************************
   Step 1: Enabling the HSI clock - RCC_CR bit (If not enabled)
  		   HSION = 1 HSI : oscillator on
   Step 2: Waiting until HSI clock is ready an can be used as Clock Source 
           RCC_CR bit HSIRDY = 0 : Oscillator Not Ready
		   RCC_CR bit HSIRDY = 1 : Oscillator Ready
   Step 3: Select HSI in SW[1:0] as Clock Source
           RCC_CFGR bits SW[1:0] = 00 : HSI selected
   Step 4: Select AHB prescaler=1 
           RCC_CFGR bits HPRE[3:0] = 0000 
   Step 5: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 0 Wáit States(section 3.3) 
  		   LATECY[2:0] = 000 - Zero wait state. ( 0 Hz  < SYSCLK <= 24 Mhz)
  		   LATECY[2:0] = 001 - One wait state.  (24 MHz < SYSCLK <= 48 Mhz)
  		   LATECY[2:0] = 010 - Two wait state.  (48 MHz < SYSCLK <= 72 Mhz)
   Step 6: Disabling HSE Clock- RCC_CR bit
  		   HSEON = 0 : oscillator off
*/
void rcc_clockmode1( void ) {
  	// Step 1 - Enabling the HSI clock - If not enabled and ready
	if ( (RCC->CR & RCC_CR_HSIRDY) == 0) {
 	  RCC->CR |= RCC_CR_HSION;  // HSION=1
	
	  //Step 2 - Waiting until HSI clock is ready
	  while ((RCC->CR & RCC_CR_HSIRDY) == 0) {}; // Wait HSIRDY = 1
	}
	//Step 3: Select HSI in SW[1:0] as Clock Source
	//         Take care. SW[1:0] Select the clock source
	RCC->CFGR &= 0xfffffffc;

	//Step 4: Select AHB prescaler=1 
	RCC->CFGR &= 0xffffff0f; // HPRE[3:0] = 0000

    //Step 5: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 0 Wáit
	FLASH->ACR &= 0xfffffff8; //LATENCY[2:0] = 000
	
	//Step 6: Disabling HSE Clock- RCC_CR bit
	RCC->CR &= ~RCC_CR_HSEON;

}
/* sub rcc_clockmode5()
   abstract: Select HSE as System Clock with,
     Crystal  = 25 MHz
	 SYSCLK   = 72 MHz
	 FCLK     = 72 MHz
	 OTGFSCLK = 48 MHz (USB)
	 ADC clock= 12 MHz 


   input...:  -

   output..: -
   limits..: No errorcheck performed
   *********************************************
   See: http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS/Clock_Paths
        http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS
   *********************************************
   
   To select the frequencies 72 MHz as SYSCLK from 25 MHz Crystal the
   following calculation is necesary 25 MHz / 5 * 16 / 10 * 9 = 72 MHz
   
   PREDIV2 - Divide by 5
   PLL2MUL - Multiply by 16
   PREDIV1 - Divide by 10
   PLLMUL  - Multiply by 9  
   
   Step  0: HSEBYP default = 0 (Using Crystral = default)
   Step  1: Shift to Clockmode=1 (Freeing the Clock Path for programming)
   Step  2: Enabling the HSE clock - RCC_CR bit
  		   HSION = 1 HSE : oscillator on
   Step  3: Waiting until HSE clock is ready an can be used as Clock Source 
           RCC_CR bit HSERDY = 0 : Oscillator Not Ready
		   RCC_CR bit HSERDY = 1 : Oscillator Ready
   Step  4: Select RCC_CFGR2 PREDIV2[3:0] divide by 5 =  0100
   Step  5: Disable RCC_CR PLL2ON = Disable (Shut down PLL2MUL)
   Step  6: Select RCC_CFGR2 PLL2MUL[3:0] multiply by 16 = 1110
   Step  7: Enable RCC_CR PLL2ON = Enable (Start pll2MUL after programmed)
   Step  8: Wait for PLL2MUL to lock RCC_CR bit PLL2RDY = 1
   Step  9: Select PLL2MUL as PREDIV1SRC - RCC_CFGR2 bit PREDIV1SRC = 1
   Step 10: Select RCC_CFGR2 PREDIV1[3:0] divide by 10 = 1001
   Step 11: Select PREDIV1 as PLLSRC - RCC_CFGR bit PLLSRC = 1
   Step 12: Disable RCC_CR bit PLLON = 0
   Step 13: Select RCC_CFGR PLLMUL[3:0] multiply by 9 = 0111
   Step 14: Enable RCC_CR bit PLLON = 1
   Step 15: Wait for PLLMUL to lock RCC_CR bit PLLRDY = 1
   Step 16: USB Prescaler divide by 3 ( 72 Mhz * 2 / 3 )  = 48 MHz
            RCC_CFGR bit OTGFSPRE = 0
   Step 17: Select AHB prescaler=1 - RCC_CFGR bits HPRE[3:0] = 0000
   Step 18: Enable prefetch FLASH_ACR bit PRFTBE = 1
   Step 19: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 2 Wáit States(section 3.3) 
  		    LATECY[2:0] = 000 - Zero wait state. ( 0 Hz  < SYSCLK <= 24 Mhz)
  		    LATECY[2:0] = 001 - One wait state.  (24 MHz < SYSCLK <= 48 Mhz)
  		    LATECY[2:0] = 010 - Two wait state.  (48 MHz < SYSCLK <= 72 Mhz) 
   Step 20: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
   Step 21: RCC_CFGR bits ADCPRE[1:0] = 10 ADC-prescaler divide by 6 72 MHz / 6 = 12 MHz
   Step 22: Select PLLCLK in SW[1:0] as Clock Source
            RCC_CR SW[1:0] = 10
   Step 23: Disabling HSI Clock- RCC_CR bit
  		   HSION = 0 : oscillator off
           RCC_CFGR bits SW[1:0] = 00 : HSI selected
*/
void rcc_clockmode5( void ) {
int i;
	//Step  1: Shift to Clockmode=1
	rcc_clockmode1();

	// Step 2 - Enabling the HSE clock
 	RCC->CR |= RCC_CR_HSEON;  // HSEON=1
	
	//Step 3 - Waiting until HSE clock is ready
	while ((RCC->CR & RCC_CR_HSERDY) == 0) {}; // Wait HSERDY = 1

	//Step  4: Select RCC_CFGR2 PREDIV2[3:0] divide by 5 =  0100 (bits[7:4])
	RCC->CFGR2 |= 0x00000040; // Setting bit x1xx
	RCC->CFGR2 &= 0xffffff4f; // Resetting bit 0x00

    //Step  5: Disable RCC_CR PLL2ON = Disable (Shut down PLL2MUL)
	RCC->CR &= ~( 1 << 26 ); // Resetting bit 26 disabling PPL2MUL

	//Step  6: Select RCC_CFGR2 PLL2MUL[3:0] multiply by 16 = 1110 (bits[11:8])
	RCC->CFGR2 |= 0x00000e00; // Setting bits 111x
	RCC->CFGR2 &= 0xfffffeff; // Resetting bit xxx0

	//Step  7: Enable RCC_CR PLL2ON = Enable (Start pll2MUL after programmed)
	RCC->CR |=  1 << 26 ; // Setting bit 26 enabling PPL2MUL

	//Step  8: Wait for PLL2MUL to lock RCC_CR bit PLL2RDY = 1
	while ((RCC->CR & RCC_CR_PLL2RDY) == 0) {}; // Wait PLL2RDY = 1

	//Step  9: Select PLL2MUL as PREDIV1SRC - RCC_CFGR2 bit PREDIV1SRC = 1
	RCC->CFGR2 |= 1 << 16; // Setting bit 16 selecting PLL2MUL

	//Step 10: Select RCC_CFGR2 PREDIV1[3:0] divide by 10 = 1001 (bits[3:0])
	RCC->CFGR2 |= 0x00000009; // Setting bits 1xx1
	RCC->CFGR2 &= 0xfffffff9; // Resetting bit x00x

	//Step 11: Select PREDIV1 as PLLSRC - RCC_CFGR bit PLLSRC = 1
	RCC->CFGR |= RCC_CFGR_PLLSRC;

	//Step 12: Disable RCC_CR bit PLLON = 0
	RCC->CR &= ~( 1 << 24 ); // Resetting bit 24 disabling PPLMUL

	//Step 13: Select RCC_CFGR PLLMUL[3:0] multiply by 9 = 0111	(bits[21:18])
	RCC->CFGR &= ~( 1 << 21 ); // Bit 21 = 0
	RCC->CFGR |= 1 << 20; 		// bit 20 = 1
	RCC->CFGR |= 1 << 19; 		// bit 19 = 1
	RCC->CFGR |= 1 << 18; 		// bit 18 = 1

	//Step 14: Enable RCC_CR bit PLLON = 1
	RCC->CR |=  1 << 24 ; // Setting bit 24 enabling PPLMUL

	//Step 15: Wait for PLLMUL to lock RCC_CR bit PLLRDY = 1
	while ((RCC->CR & RCC_CR_PLL1RDY) == 0) {}; // Wait PLL1RDY = 1

	//Step 16: USB Prescaler divide by 3 ( 72 Mhz * 2 / 3 )  = 48 MHz
	RCC->CFGR &= ~(1 << 22); //Resetting OTGFSPRE selects divide by 3

	//Step 17: Select AHB prescaler=1 - RCC_CFGR bits HPRE[3:0] = 0000 (bits[7:4])
	RCC->CFGR2 &= 0xffffff0f; // Resetting bit 0000

	//Step 18: Enable prefetch FLASH_ACR bit PRFTBE = 1
	FLASH->ACR |= 1 << 4;

	//Step 19: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 2 Wáit States(section 3.3)
	FLASH->ACR |= 0x00000002;
	FLASH->ACR &= 0xfffffffa;
	
	for(i=0;i < 100000;i++);

	//Step 20: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
	rcc_cfgr( 0x00000300, 0 ); //Set PPRE1[1:0] = 0
	rcc_cfgr( 0x00000400, 1 ); //Set PPRE1[2] = 1

	//Step 21: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
	rcc_cfgr( 1 << 14, 0 ); //Set ADCPRE[0] = 0
	rcc_cfgr( 1 << 15, 1 ); //Set ADCPRE[1] = 1
	
	//Step 22: Select PLLCLK in SW[1:0] as Clock Source
	RCC->CFGR |= RCC_CFGR_PLLON;

   //Step 23 - Disable HSI
	RCC->CR &= ~RCC_CR_HSION;
}

Add rcc.h

extern void rcc_clockmode1( void );
extern void rcc_clockmode3( void );
extern void rcc_clockmode4( void );
extern void rcc_clockmode5( void );

Use clockmode 5 in main.c

Add rcc_clockmode5(); before main loop Template:Souce cli