历史上的今天
今天是:2024年12月18日(星期三)
2018年12月18日 | STM32时钟初始化研究
2018-12-18 来源:eefocus
时钟是一个MCU的脉搏,研究清楚脉搏才能更清楚的把握整个MCU的运行。本文主要研究STM32F10x系列,利用官方库文件进行初始化设置。开发环境为MDK4.6,库文件V3.5版本,STM32参考手册。
利用MDK自带仿真器,仿真发现。芯片启动首先打开system_stmf10x.c文件,调用void SystemInit(void)函数。下面贴上代码和中文注释
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001; //内部高速时钟使能
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
//SW:HSI(内部高速8M RC震荡器)作为时钟源
//AHB(SYSCLK)不分频
//APB1,APB2不分频
// PCLK2 2分频后作为ADC时钟
// HSI时钟2分频后作为PLL输入时钟
//MCO没有时钟输出
RCC->CFGR &= (uint32_t)0xF8FF0000;
/* Reset HSEON, CSSON and PLLON bits */
//HSE振荡器关闭, 时钟安全系统监测器关闭PLL关闭
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
//清零来旁路外部晶体振荡器。只有在外部4-25MHz振荡器关闭的情况下,才能写入该位。
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
//HSI时钟2分频后作为PLL输入时钟
//HSE不分频器作为PLL输入
//0000:PLL 2倍频输出
//0:PLL时钟1.5倍分频作为USB时钟
RCC->CFGR &= (uint32_t)0xFF80FFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
}
主要是用于重置RCC寄存器,既重置STM32的时钟树。
初始化重置时钟后的时钟树图:

上文中还有个函数叫SetSysClock用于设置MCU系统时钟,贴入代码:
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
/* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */
}
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSE */
/*define C_CR_HSEON (int32_t)0x00010000) */
/*!< External High Speed clock enable */
//开启HSE振荡器
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
//等待HSE起振
//#define HSEStartUp_TimeOut HSE_STARTUP_TIMEOUT
//#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500)
/*!< Time out for HSE start up */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)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 */
//#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */
//HCLK :AHB总线时钟,由系统时钟SYSCLK 分频得到,不分频
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
// #define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */
//APB2由AHB分频而来,不分频。
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
//#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */
//APB1由AHB分频而来,2分频。
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
//设置PLLCLK时钟源为HSE,且PLL9倍频
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);
/* Enable PLL */
//使能倍频器
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
//等待PLL稳定运行
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
//设置PLL作为系统时钟源
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Wait till PLL is used as system clock source */
//等待PLL用于系统时钟源
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
else
{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
}
}
初始化重置时钟后的时钟树图:

上一篇:stm32时钟初始化分析
下一篇:STM32F4各外设时钟配置总结
史海拾趣
|
如题。直接接在普通开关两端的延时开关电路,不用改变目前的布线方式直接接与开关两端, 可用原开关两端引出两个线作为一个控制信号,也可以加上声控,光控功能, 下图这个电路当可控硅导通时5,8两端的电压最多只有2V,怎么解决后面电路的供电问 ...… 查看全部问答> |
|
求教: 本人做了一个16*16的LED屏,它是由89C52+74HC154控制 P0和P2口控制行(LED的阳级) P1口连接74HC154控制列(LED阴级) 现在问题是输出的字是看不懂,求高手指点. uchar code hanzi[]={ 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x ...… 查看全部问答> |
|
两年一届的“全国大学生电子设计竞赛”已经成为全国各高校师生热切盼望的一项重大赛事和广泛开展类似竞赛活动的实践平台。十余年来,竞赛“政府主办,专家主导,学生主体,社会参与”的组织运行模式也在不断完善,有力推动了教育教学改革,为人才培 ...… 查看全部问答> |
|
usb虚拟串口通信问题请问大家有没有遇到这样的情况,在移植str71x usb developer kit的虚拟串口的例子的过程中,发现一个奇怪的现象:利用串口调试助手发送相应的数据,str711接收很正常,但是当str711向计算机端发送数据时, ...… 查看全部问答> |
|
显示三维图像的LED吊灯 这是一家名为NOVA的公司为瑞士苏黎世理工学院150年校庆设计的一盏超华丽的吊灯,5米见方,厚1米,重达3.3吨,一共用了300000颗LED,12颗为一组,球形灯泡封装,能显示1600万种颜色~而最厉害的地方在于,由于它厚达1米,LED ...… 查看全部问答> |
|
使用的是freescale dsp 8157(6核),目前只能调试核0,在debug configuration中选择其他核时无法仿真(不会进入到该核的程序入口),不知需要怎样配置才行。 谢谢… 查看全部问答> |




