×

理解STM32系统时钟和分频资料下载

消耗积分:3 | 格式:pdf | 大小:102.83KB | 2021-04-20

贾伟刚

分享资料个

系统时钟和分频 首先来手册里的一段话。 三种不同的时钟源可被用来驱动系统时钟 (SYSCLK) HSI振荡器时钟 HSE振荡器时钟 PLL时钟 一般用的是PLL时钟,后面有证据。 我们可以通过库函数获取各时钟值 void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) 在我的系统里,把时钟值打印信息如下: SYSCLK:0x44aa200 //72000000, 72MHz HCLK:0x44aa200 //72000000, 72MHz PCLK1:0x2255100 //36000000, 36MHz PCLK2:0x44aa200 //72000000, 72MHz ADCCLK:0x2255100 //36000000,36MHz RCC->CFGR:0x001D040A //PLL输出作为系统时钟 可推测几个预分频值为 AHB prescaler = 1 APB1 prescaler = 2 APB2 prescaler = 1 ADC prescaler = 2 根据读取RCC->CFGR寄存器值为:0x001D040A,上面推测完全正确。 CFGR寄存器的SWS段也说明:PLL输出作为系统时钟。 TIM2使用PCLK1,但注意时钟树里有这一段 见附图 已知APB1 prescaler=2,故TIM2CLK = PCLK1*2 = 72MHz. 所以被TIM2分频的时钟大小是72MHz。 我的程序也证明了这点 TIM_TimeBaseInitTypeDef tim2_InitStruct; TIM_DeInit(TIM2); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//Enable Timer2 clock. NVIC_ConfigurationForTimer2(); // PCLK1=36MHz, PSC=36000-1, CK_CNT=36MHz/(PSC 1)=1000 // ARR=2000, 1s/1000 * 2000 = 2s. tim2_InitStruct.TIM_Prescaler = 36000-1; tim2_InitStruct.TIM_Period = 2000-1; tim2_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; tim2_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; tim2_InitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &tim2_InitStruct); TIM_ClearFlag(TIM2, TIM_FLAG_Update); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//Enables the specified TIM interrupts. 这段配置原本以为定时时间是2s,实际只有1s。看了手册才理解原因。 摘自: STM32 RCC复位与时钟配置,我首先忽略掉复位,首先学习时钟配置,复位以后用到再学习 STM32有多个时钟源,分别是 HSI:上电默认启动,因精度不高所以先不采用,以后如果需要再使用 HSE:外部高速时钟,系统时钟一般采用它,经过PLL倍频作为系统同时钟 LSE:外部低速时钟,一般专门用于RTC,等到RTC模块时再使用 LSI:内部低速时钟,精度不高,一般用于IWDGCLK 时钟系统框图如下: STM32中各个模块都有自己的时钟,当使用相应的模块时首先记得把此模块时钟开启 本次学习使用标准固件库3.3.0 好了,看明白上图咱就开始吧: void RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; //SystemInit(); //完全可以使用此函数配置,但是为了学习咱先不用 RCC_DeInit(); //复位RCC模块的寄存器,复位成缺省值 RCC_HSEConfig(RCC_HSE_ON); //开启HSE时钟,咱是用HSE的时钟作为PLL的时钟源 HSEStartUpStatus = RCC_WaitForHSEStartUp(); //获取HSE启动状态 if(HSEStartUpStatus == SUCCESS) //如果HSE启动成功 { FLASH_PrefetchBufferCmd(ENABLE); //开启FLASH的预取功能 FLASH_SetLatency(FLASH_Latency_2); //FLASH延迟2个周期(这里我也不明白,先用吧) RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置HCLK,PCLK2,PCLK1,PLL RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); RCC_PLLCmd(ENABLE); //启动PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET) {} //等待PLL启动完成 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系统时钟 while(RCC_GetSYSCLKSource() !=0x80) //检查是否将HSE 9倍频后作为系统时钟 {} } } 设置时钟流程: 1.将RCC寄存器重新设置为默认值 RCC_DeInit 2.打开外部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON); 3.等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp(); 4.设置AHB时钟 RCC_HCLKConfig; 5.设置高速APB2时钟 RCC_PCLK2Config; 6.设置低速速APB1时钟 RCC_PCLK1Config 7.设置PLL RCC_PLLConfig

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !