在处理器正常工作前,肯定要做一些初始化工作,其中最主要的一个就是初始化各种时钟。通过对STM32F103的复位及时钟控制(RCC)模块分析之后,自己写了一个RCC的头文件,这样使用起来更方便。头文件中首先定义了最基本的几个寄存器,然后再对每个寄存器中的域使用结构体做了定义,可以直接使用寄存器中的位来操作。注意设置系统时钟时要先设置好FLASH的等待周期,不然程序就可能会跑飞。
系统时钟初始化的代码如下:
//以下时钟配置为最高性能
void SystemClockInit(void)
{
//设置flash等待周期为2,否则设置为72M系统时钟时就会跑飞
FLASH_ACR=0x32;
pbRCC_CR->HSEON=1; //使能外部高速时钟
while(!(pbRCC_CR->HSERDY)); //等待外部高速时钟稳定
pbRCC_CFGR->MCO=0; //MCO无时钟输出
pbRCC_CFGR->USBPRE=1; //USB时钟1.5分频
pbRCC_CFGR->PLLMUL=9-2; //PLL倍频设置为9倍(外部时钟8M,PLL输出72M)
pbRCC_CFGR->PLLXTPRE=0; //HSE不分频
pbRCC_CFGR->PLLSRC=1; //HSE选作做为PLL时钟源输入
pbRCC_CFGR->ADCPRE=0; //ADC时钟2分频
pbRCC_CFGR->PPRE2=1+6; //APB2设置为1分频
pbRCC_CFGR->PPRE1=2+6; //APB1设置为2分频
pbRCC_CFGR->HPRE=0; //AHB无分频
pbRCC_CR->PLLON=1; //启动PLL
while(!(pbRCC_CR->PLLRDY)); //等待PLL稳定
pbRCC_CFGR->SW=2; //选择PLL输出为时钟源
//pbRCC_AHBENR->SRAMEN=1;
//pbRCC_AHBENR->FLITFEN=1;
//IO口第二功能时钟使能
pbRCC_APB2ENR->AFIOEN=1;
//各通用IO口时钟使能
pbRCC_APB2ENR->IOPAEN=1;
pbRCC_APB2ENR->IOPBEN=1;
pbRCC_APB2ENR->IOPCEN=1;
pbRCC_APB2ENR->IOPDEN=1;
pbRCC_APB2ENR->IOPEEN=1;
//ADC时钟使能
pbRCC_APB2ENR->ADC1EN=1;
pbRCC_APB2ENR->ADC2EN=1;
//定时器1时钟使能
pbRCC_APB2ENR->TIM1EN=1;
//SPI1时钟使能
pbRCC_APB2ENR->SPI1EN=1;
//串口1时钟使能
pbRCC_APB2ENR->USART1EN=1;
//定时器2、3、4时钟使能
pbRCC_APB1ENR->TIM2EN=1;
pbRCC_APB1ENR->TIM3EN=1;
pbRCC_APB1ENR->TIM4EN=1;
//窗口看门狗时钟不使能
pbRCC_APB1ENR->WWDGEN=0;
//SPI2时钟使能
pbRCC_APB1ENR->SPI2EN=1;
//串口2、3时钟使能
pbRCC_APB1ENR->USART2EN=1;
pbRCC_APB1ENR->USART3EN=1;
//I2C1、2时钟使能
pbRCC_APB1ENR->I2C1EN=1;
pbRCC_APB1ENR->I2C2EN=1;
//USB时钟使能
pbRCC_APB1ENR->USBEN=1;
//CAN时钟使能
pbRCC_APB1ENR->CANEN=1;
//备份接口时钟使能
pbRCC_APB1ENR->BKPEN=1;
//电源接口时钟使能
pbRCC_APB1ENR->PWREN=1;
//外部低速时钟启动
pbRCC_BDCR->LSEON=1;
pbRCC_BDCR->LSEBYP=0;
pbRCC_BDCR->RTCSEL=1; //选择外部时钟为RTC时钟
}