stm32的HSI能够达到8MHZ,但是通过软件的设置,能够让stm32工作在72MHZ。接下来,就来完整的写一遍时钟设置函数。
stm32通过操纵寄存器到达编程控制硬件的目的。因此,首先要开一个.h的头文件做一些基本的设置。

#ifndef __CLOCK_H__
#define __CLOCK_H__

接下来,在这其中做一些寄存器的宏定义:

#define RCC_BASE    0x40021000
#define RCC_CR        ( RCC_BASE + 0x00 )
#define RCC_CFGR   ( RCC_BASE + 0x04 )

当然,如果想要使用寄存器,那么就要对寄存器进行指针解引

#define rRCC_CR        *( ( unsigned int * ) RCC_CR )
#define rRCC_CFGR   *( ( unsigned int * ) RCC_CFGR )
#endif

以上,基本上,就已经把所需要的寄存器配置好了。
然后,新建一个.c文件,开始写时钟设置函数,那么将这个时钟设置函数命名为:void Set_SysClockTo72M(void);
在这个函数中,首先,进行一个基本的变量定义:

unsigned int rccCrHserdy = 0;
unsigned int rccCrPllrdy = 0;
unsigned int rccCrSw = 0;
unsigned int faultTime = 0;

首先,要复位RCC_CR寄存器:rRCC_CR = 0x00000083;
接着,开启外部时钟,此时,对RCC_CR寄存器的bit16进行设置,若为0,HSE振荡器禁用;若为1,HSE振荡器打开。
首先对bit16清零,然后才是配置。

rRCC_CR &= ~( 1 << 16 );
rRCC_CR |= ( 1 << 16 );

任何一个时钟的开启都是需要时间的,因此,我们需要检测时钟的开启是否成功,如果成功,则继续进行,如果失败,则陷入死循环。

do
    {
        rccCrHserdy = rRCC_CR & ( 1 << 17 );
        faultTime++;
    }while ((faultTime<0x0FFFFFFF) && (rccCrHserdy==0));

其实,接下来,还有一个flash的配置问题,但是由于我对于flash的配置和时钟有什么关系不太清楚,所以就不写了。
接下来,是对AHB,APB2,APB1进行设置。AHB不分频,APB2不分频,APB1两分频。因为,APB1最大只能达到36MHZ。

rRCC_CFGR &= ( ~( ( 0x0f << 4 ) | ( 0x07 << 8 ) | ( 0x07 << 11 ) ) );
rRCC_CFGR |= ( 0x00 << 4 | 0x04 << 8 | 0x00 << 11 );

HSE要设置为输入时钟,同时不分频。对HSE的设置,是对STM32的bit16,bit17进行设置。若对bit16进行置位操作,则HSE振荡器被选作PLL输入时钟;若对bit16进行复位操作,则HSI/2s振荡器被选作PLL输入时钟。若对,bit17进行置位操作,则HSE两分频;若对bit17进行复位操作,则HSE时钟未被分频。

rRCC_CFGR &= ( ~( 0x01 << 16 | 0x01 << 17 )  );
rRCC_CFGR  |= ( 0x01 << 16 | 0x00 << 17  );

要让8MHZ的CPU工作在72MHZ,就要对PLL进行9倍频。

rRCC_CFGR &= ~( 0x0f << 18 );
rRCC_CFGR |= ( 0x07 << 18 );

接下来,就是打开PLL使能。

rRCC_CR |= 0x01 << 24;

时钟的开启,需要时间,因此,需要判断是否开启成功。

faultTime = 0;
        do
        {
            rccCrPllrdy = rRCC_CR & ( 1 << 17 );
            faultTime++; 
        }while ( ( faultTime < 0x0FFFFFFF ) && rccCrPllrdy == 0 );

接下来,就是,将PLL作为,SYSCLK的时钟来源。因此,我们要对配置寄存器的bit0及bit1进行操作。若将bit1及bit0置为00,则HSI被选作系统时钟;若bit1及bit0置为01,则HSE被选作系统时钟;若将bit及bit0置为10,则PLL被选作系统时钟。

rRCC_CFGR &= ~( 0x03 << 0 );
rRCC_CFGR |= 0x02 << 0;

最后,就是进行一个判断,判断是否成功将PLL作为系统时钟,若成功,则该函数完毕;若失败,则该函数陷入死循环。