分类: 嵌入式
2011-11-03 08:27:36
时钟源:
1, HSI:内部高速时钟 stm32内带的时钟(8M频率) 精度较差
2, HSE:4-16MHz高速外部时钟 精度高来自 (1) HSE外部晶体/陶瓷谐振器(晶振)(2 )HSE用户外部时钟
3 LSE:低速外部晶体 32.768Khz 主要提供一个精确地时钟源,用来选择性的驱动实时时钟(RTC-CLK)
4 LSI:32kHz低速内部晶体振荡器一般用来驱动独立的看门狗和选择性的驱动用于从停止/待机模式自动唤醒的RTC
具体流程:
HIS,HSE通过倍频形成PLLCLK——>PLLCLK供给USBCLK,并且HIS和HSE 和PLLCLK 共同组成SYSCLK,64MHz——>通过预分频器将AHB的频率升到72MHz——>AHB的频率分给HCLK(1用于DMA,AHB bus,core,memory,2供给Coretex系统定时器的外部时钟,可设置SysTick寄存器3FCLK,自由运行时钟 ),并且供给APB用于供给外设
各种时钟介绍
HSI 8MHz
HSE 4-16MHz
PLL 输出48MHzUSBCLK
LSE 32.768KHz 通过RCC_BDCR 的LSEON位控制
RCC_BDCR的LSERDY位指示了LSE晶体振荡器是否稳定
若在时钟中断寄存器(RCC_CIR)中打开了的话,将会产生一个中断
LSI 32KHz 通过RCC_CSR的LSION位打开或禁止
RCC_CSR的LSIRDY标志指示了是否稳定
SYSCLK时钟
系统复位之后,HIS振荡器被选作系统时钟,若要切换时钟源,必须等到目标始终切换好了之后。可以通过看RCC_CR的状态位来看那些时钟源准备好了。
RTC时钟(RTCCLK)
时钟源可以是LSE,LSI,HSE/128,选择哪个,可以通过RCC_BDCR的RTCSEL[1:0]位来选择,这个修改复位备份区域才能修改。
MCO 时钟输出性能
输出到MCO引脚,相关的GPIO引脚必须编程为复用功能。
下面四个时钟信号的一个可被选作MCO的时钟
SYSCLK
HIS
HSE
2分频的PLL
可通过RCC_CFGR的MCO[2:0]位进行选择
SysTick定时器时钟源可以是FCLK自由运行时钟,也可以是外部时钟源,选择取决于它的控制及状态寄存器的CLKSOURCE位
设置始终流程
1 将RCC寄存器重新设置位默认值 RCC_DeInit//使能控制,如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等。
2 打开外部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON)
3 等待外部高速时钟晶振工作 HSEStartUpStatus=RCC_WaitForHSEStartUp()
4 设置AHB时钟 RCC_HCLKConfig;
5设置高速AHB时钟 RCC_PCLK2Config
6 设置低速AHB时钟 RCC_PCLK1Config
7 设置PLL RCC_PLLConfig
8 打开PLL RCC_PLLCmd(ENABLE);
9 等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
10 设置系统时钟 RCC_SYSCLKConfig
11 判断是否PLL是系统时钟 while(RCC_GetSYSCLKSource()!=0x08)
12 打开要使用的外设时钟
RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()
typedef struct
{
vu32 CR;
vu32 CFGR;
vu32 CIR;
vu32 APB2RSTR;
vu32 APB1RSTR;
vu32 AHBENR;
vu32 APB2ENR;
vu32 APB1ENR;
vu32 BDCR;
vu32 CSR;
} RCC_TypeDef;
Static void RCC_Config(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus==SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//使能flash预缓冲区
FLASH_SetLatency(FLASH_Latency_2);
//令Flash处于等待状态,2是针对高频时钟的
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置高速总线时钟=系统时钟
RCC_PCLK2Config(RCC_HCLK_Div1);设置低速总线2时钟=高速总线时钟
RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速总线1的时钟=高速时钟的二分频
RCC_ADCCLKConfig(RCC_PCLK2_Div6);设置ADC外设时钟=低速总线2时钟的六分频
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);利用锁相环将外部8MHz晶振9倍频道72MHz
RCC_PLLCmd(ENABLE);
While(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
While(RCC_GetSYSCLKSource()!=0x08)//0x00HSI作为系统时钟 0x04 HSE 0x08 PLL
{}
}
/*使能FSMC,GPIOD,GPIOE,GPIOF,GPIOG and AFIO时钟*/
//使能外围接口总线时钟,注意各外设的隶属情况,不同芯片的分配不同
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);
RCC_AHB2PeriphClockCmd(RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF| RCC_APB2Periph_GPIOG| RCC_APB2Periph_AFIO,ENABLE);
}
该电路板式8MHz晶振,系统时钟9倍频道72MHz,AHB高速总线时钟为72MHz,AHB低速2总线72MHz,AHB低速1总线为36MHz,ADC为12MHz
USB经过1.5分频设置就可以实现48MHz数据传递
STM32之时钟树
用户可通过多个预分频器配置AHB总线、高速APB2总线和低速APB1总线的频率。AHB和APB2域的最大频率是72MHZ。APB1域的最大允许频率是36MHZ。SDIO接口的时钟频率固定为HCLK/2。
l 40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。另外,实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。RTC的时钟源通过RTCSEL[1:0]来选择。
l STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。该时钟源只能从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz。
l 另外,STM32还可以选择一个PLL输出的2分频、HSI、HSE、或者系统时钟输出到MCO脚(PA8)上
l 系统时钟SYSCLK,是供STM32中绝大部分部件工作的时钟源。系统时钟可选择为PLL输出、HSI或者HSE,在选择时钟源前注意要判断目标时钟源是否已经稳定振荡。Max=72MHz,它分为2路,1路送给I2S2、I2S3使用的I2S2CLK、I2S3CLK;另外1路通过AHB分频器分频(1/2/4/8/16/64/128/256/512)分频后送给以下8大模块使用:
① 送给SDIO使用的SDIOCLK时钟。
② 送给FSMC使用的FSMCCLK时钟。
③ 送给AHB总线、内核、内存和DMA使用的HCLK时钟。
④ 通过8分频后送给Cortex的系统定时器时钟(SysTick)。
⑤ 直接送给Cortex的空闲运行时钟FCLK。
⑥ 送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给定时器(Timer2-7)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4、5、6、7使用。
⑦ 送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer1、Timer8)1、2倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用。另外,APB2分频器还有一路输出供ADC分频器使用,分频后得到ADCCLK时钟送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。
⑧ 2分频后送给SDIO AHB接口使用(HCLK/2)
2 时钟输出的使能控制
在以上的时钟输出中有很多是带使能控制的,如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等。
l 当需要使用某模块时,必需先使能对应的时钟。
l 需要注意的是定时器的倍频器,当APB的分频为1时,它的倍频值为1,否则它的倍频值就为2。
l 连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4。注意USB模块虽然需要一个单独的48MHz时钟信号,但它应该不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟。USB模块工作的时钟应该是由APB1提供的。
l 连接在APB2(高速外设)上的设备有:GPIO_A-E、USART1、ADC1、ADC2、ADC3、TIM1、TIM8、SPI1、ALL。
底层函数剖析
void SystemInit (void)或者RCC_DeInit()
{
RCC->CR |= (uint32_t)0x00000001;//使能内部高速时钟
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;//MCO系统时钟被选择,ADC时钟频率为PLCK2 二分频,APB高速(APB2)HCLK未被分频,APB低速HCLK未被分频,SYSCLK未被分频,HSI振荡器被用作系统时钟,软件置位HSI振荡器被用作系统时钟
#else
RCC->CFGR &= (uint32_t)0xF0FF0000; //MCO未被选择,ADC时钟频率为PLCK2 二分频,APB高速(APB2)HCLK未被分频,APB低速HCLK未被分频,SYSCLK未被分频,HSI振荡器被用作系统时钟,软件置位HSI振荡器被用作系统时钟
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;//PLL禁用,时钟检测器CSS禁用,//HSE振荡器禁用
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;//外部高速振荡器未被旁路
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;//USB时钟是PLL1.5分频,当禁用//PLL情况下,由软件写入以定义PLL的倍频参数,位【21:18】0000表示PLL 时钟2倍频
#ifndef STM32F10X_CL
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#else
/* 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;
#endif /* STM32F10X_CL */
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
}