sysclock.h文件:
#ifndef __SYSCLOCK_H
#define __SYSCLOCK_H
#include "stm32f10x.h"
void My_HSE_SetSysClock(void);
#endif
sysclock.c文件:
#include "sysclock.h"
/*
* RCC相关寄存器初始化
*/
static void My_RCC_DeInit()
{
/* 内部高速时钟使能 */
RCC->CR |= (uint32_t)0x00000001;
/* 复位 SW SWS HPRE PPRE1 PPRE2 ADCPRE MCO*/
RCC->CFGR &= (uint32_t)0xF8FF0000;
/* HSE振荡器关闭 时钟监测器关闭 PLL关闭 */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* 外部4-25MHz振荡器没有旁路 */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* HSI时钟2分频后作为PLL输入时钟 HSE不分频 PLL 2倍频输出 PLL时钟1.5倍分频作为USB时钟*/
RCC->CFGR &= (uint32_t)0xFF80FFFF;
/* 关闭所有中断 */
RCC->CIR &= 0x009F0000;
}
/*
* 检查高速外部时钟是否就绪
* 返回值 SUCCESS:已经就绪 ERROR:未就绪
*/
static ErrorStatus My_RCC_WaitForHSEStartUp(void)
{
__IO uint32_t StartUpCounter = 0;
uint32_t tmpreg = 0;
do
{
tmpreg = RCC->CR ;
tmpreg &= ((uint32_t)0x01)<<17;
StartUpCounter++;
}while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (tmpreg == RESET));
if((RCC->CR & (((uint32_t)0x01)<<17)) != RESET) return SUCCESS;
else return ERROR;
}
/**
* 简介:外部高速晶振配置为系统时钟
*/
void My_HSE_SetSysClock(void)
{
__IO uint32_t StartUpCounter = 0, HSEStartUpStatus = 0;
__IO uint32_t tmpreg = 0;
My_RCC_DeInit();
/* HSE振荡器开启 */
RCC->CR |= ((uint32_t)0x00010000);
/* 检查外部高速时钟是否就绪 */
if(My_RCC_WaitForHSEStartUp()) HSEStartUpStatus = 0x01;
else HSEStartUpStatus = 0x00;
if(HSEStartUpStatus == 0x01)
{
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* HSE时钟作为PLL输入时钟 HSE不分频作为PLL输入 PLL倍频系数 = 9 */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* 使能PLL */
RCC->CR |= (0x01)<<24;
/* 等待PLL稳定 */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* 系统时钟切换 PLL作为系统时钟 */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* 等待PLL配置为系统时钟*/
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}else while(1);
}
启动文件调用:
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT My_HSE_SetSysClock
LDR R0, =My_HSE_SetSysClock
BLX R0
LDR R0, =__main
BX R0
ENDP
亲测可用:
参考资料:STM32库函数源码;