Clock Tree
1> 时钟系统 总框图
STM32F103ZET6:
主干道:
STM32F103内部简化方框图:
STM32F103时钟框图:
时钟框图与STM32F103内部框图对照看,更有感觉
2> HSE 高速外部时钟
HSE: 高速外部时钟(High Speed External clock signal)
外接晶振8MHz,为保证STM32工作稳定,选择外部晶振提供时钟源;
SYSCLK:72MHz
外部晶振【8MHz】 >> 经过2选1选择器【PLL Source】>>
锁相环【PLL】倍频(9倍)为,8X9 = 72MHz >>
3选1选择器【System Clock】 >> SYSCLK设置为(72MHz)>>
分频器【AHB Prescaler】不分频 >> HCLK=72MHz
APB1:36MHz
72MHz送到分频器【APB1 Prescaler】2分频 ,为72÷2 = 36MHz;
为APB1上挂的外设使用;
APB2:72MHz
72MHz送到分频器【APB1 Prescaler】不分频 ,为72÷1 = 72MHz;
为APB2上挂的外设使用;
3> LSE 低速外部时钟
LSE: 低速外部时钟(Low Speed External clock signal)
外部晶振32.768KHz:为实时时钟RTC单元,提供时钟源。
2 ^ 15 = 32768, 哦哦哦,这么巧;
4> HSI 高速内部时钟
HSI: 高速内部时钟(High Speed Internal clock signal)
STM32F103ZET6 芯片内部设计了【8MHz】的RC振荡器
不需要外部晶振就可以为整个MCU提供时钟系统;
时钟频率精度较差,把HSI的8MHz输入到PLL,
可以产生最高64MHz的SYSCLK,小于外部时钟HSE的72MHz;
产品设计一般使用外部晶振;
刚开始上电时,由HSI提供时钟,可以由软件程序切换为HSE;
5> 时钟使能控制
STM32F10ZET6的许多外设时钟,
都可以通过一个【与门】来控制某个外设模块时钟的打开和关闭,
并且上电默认状态是,关闭所有外设时钟,需要哪个,必须先打开时钟;
这样做纯纯多余吗?,NO,NO,NO,是为了降低功耗。
就像滴水灌溉一样,需要哪,浇哪!
6> 标准库函数
理解STM32F103,这3样加起来看,有时单看一样不行;
1-参考手册的文字说明
2-参考手册的方框图
3-程序代码
6.1> AHB上挂的外设, 72MHz
#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001)
#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002)
#define RCC_AHBPeriph_SRAM ((uint32_t)0x00000004)
#define RCC_AHBPeriph_FSMC ((uint32_t)0x00000100)
#define RCC_AHBPeriph_SDIO ((uint32_t)0x00000400)
#define RCC_AHBPeriph_FLITF ((uint32_t)0x00000010)
#define RCC_AHBPeriph_CRC ((uint32_t)0x00000040)
6.2> APB1上挂的外设, 36MHz
#define RCC_APB1Periph_TIM2
#define RCC_APB1Periph_TIM3
#define RCC_APB1Periph_TIM4
#define RCC_APB1Periph_TIM5
#define RCC_APB1Periph_TIM6
#define RCC_APB1Periph_TIM7
#define RCC_APB1Periph_TIM12
#define RCC_APB1Periph_TIM13
#define RCC_APB1Periph_TIM14
#define RCC_APB1Periph_WWDG
#define RCC_APB1Periph_SPI2
#define RCC_APB1Periph_SPI3
#define RCC_APB1Periph_USART2
#define RCC_APB1Periph_USART3
#define RCC_APB1Periph_UART4
#define RCC_APB1Periph_UART5
#define RCC_APB1Periph_I2C1
#define RCC_APB1Periph_I2C2
#define RCC_APB1Periph_USB
#define RCC_APB1Periph_CAN1
#define RCC_APB1Periph_CAN2
#define RCC_APB1Periph_BKP
#define RCC_APB1Periph_PWR
#define RCC_APB1Periph_DAC
#define RCC_APB1Periph_CEC
APB1上主要是定时器何通信端口,共25个模块;
6.3> APB2上挂的外设, 72MHz
/* GPIO端口 */
#define RCC_APB2Periph_GPIOA
#define RCC_APB2Periph_GPIOB
#define RCC_APB2Periph_GPIOC
#define RCC_APB2Periph_GPIOD
#define RCC_APB2Periph_GPIOE
#define RCC_APB2Periph_GPIOF
#define RCC_APB2Periph_GPIOG
#define RCC_APB2Periph_AFIO
#define RCC_APB2Periph_TIM1
#define RCC_APB2Periph_TIM8
#define RCC_APB2Periph_TIM9
#define RCC_APB2Periph_TIM10
#define RCC_APB2Periph_TIM11
#define RCC_APB2Periph_TIM15
#define RCC_APB2Periph_TIM16
#define RCC_APB2Periph_TIM17
#define RCC_APB2Periph_SPI1
#define RCC_APB2Periph_USART1
#define RCC_APB2Periph_ADC1
#define RCC_APB2Periph_ADC2
#define RCC_APB2Periph_ADC3
APB2,上挂了21个模块,主要是GPIO和定时器模块;
6.4> 外设时钟使能函数
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
使能GPIOA模块的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
// GPIOA模块在APB2总线上;