求助,STM32库函数RCC
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求助,STM32库函数RCC相关的知识,希望对你有一定的参考价值。
参考技术A 看模板中main函数里这么一段代码int main(void)
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file
*/
也就是说,进入main函数前,系统已经做了时钟配置,调用的是SystemInit()函数,那么我们就进入此函数看过究竟。
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 */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
其他的我先都不想管,我就看准了这几句:
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
那么就是告诉我们,给HCLK、PCLK1和PCLK2的配置是调用 SetSysClock()函数了。
继续跟进此函数,如下:
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) */
这其实就告诉我们,SYSCLK的设置就是根据我们定义来设定,如果定义了SYSCLK_FREQ_HSE
,那么SYSCLK就是HSE(默认8MHz),如果定义了SYSCLK_FREQ_24MHz,那么SYSCLK就是24MHz,一次类推。而设置时钟是靠SetSysClockToXX()函数来实现的!
好了,既然这样,我就想继续跟进,去找SetSysClockToXX(),但是惊讶地发现,提示此函数没有定义!为啥,那是因为我去找的刚好是未被编译的,当然找不到定义,事实上这些XX函数都存在在system_stm32f10x.c文件中,但是只有一个能被跟踪找到,那就是对应的宏被定义了的那个。这些定义到底在哪?跟进!得到如下:
//system_stm32f10x.c文件
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000
#endif
这下我想起来了,每次用keil建立工程,总是要求预先定义两个宏:USE_STDPERIPH_DRIVER和STM32F10X_MD,原来这儿就体现出作用了!
因为我的芯片是STM32F10X_MD型,所以SYSCLK就被选择了72MHz!
至于static void SetSysClockTo72(void)此函数到底是怎么把SYSCLK设置成为72MHz的,我懒得去管了,代码很长,也在system_stm32f10x.c文件中,说实话我真没兴趣去搞明白,但要知道,在这个函数里,顺便把HLCK、PCLK1和PCLK2都做了默认设置!
话说回来,我真不想去看寄存器操作的,但是,这个函数里面有一个我认为是ST公司的工程师们大意写错了的地方,如下:
/* 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;
从时钟布局图中可以知道,PCLK1的最大时钟为36MHz,PCLK1怎么能等于HCLK呢?此时的HCLK可是72MHz,从下面代码也可看到,确实2分频嘛,那就是36MHz,肯定是注释错了!本回答被提问者和网友采纳
STM32F0库函数初始化系列:PWM输出
void TIM1_Configuration(void) TIM_TimeBaseInitTypeDef TIM_Time1BaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* Time 定时基础设置*/ TIM_Time1BaseStructure.TIM_Prescaler = 0; TIM_Time1BaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /* Time 定时设置为上升沿计算模式*/ TIM_Time1BaseStructure.TIM_Period = (SystemCoreClock / 40000)-1; TIM_Time1BaseStructure.TIM_ClockDivision = 0; TIM_Time1BaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_Time1BaseStructure); /* 频道1,2,3,4的PWM 模式设置 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable ;//TIM_OutputState_Enable; //PWM输出使能位 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable ;//TIM_OutputNState_Enable; //互补PWM输出使能位 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //PWM 1为有效电平 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //PWM互补 0为有效电平 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_Pulse = 600-1; //赋占空比值 TIM_OC2Init(TIM1, &TIM_OCInitStructure);//使能频道2配置 /* TIM1 计算器使能*/ TIM_Cmd(TIM1, DISABLE); /* TIM1 主输出使能 */ TIM_CtrlPWMOutputs(TIM1, DISABLE);
以上是关于求助,STM32库函数RCC的主要内容,如果未能解决你的问题,请参考以下文章