1.时钟树
时钟对于单片机来说是非常重要的,它为单片机工作提供一个稳定的机器周期从而使系统能够正常运行。时钟系统犹如人的心脏,一旦有问题整个系统就崩溃。我们知道 STM32 属于高级单片机,其内部有很多的外设,但不是所有外设都 使用同一时钟频率工作,比如内部看门狗和RTC,它只需三十几KHz 的时钟频率即可工作,所以内部时钟源就有多种选择。我们知道 STM32 系统复位后首先进入 SystemInit 函数进行时钟的设置,将 STM32F1 系统时钟设 置为 72MHz(我们开发板上使用的 STM32F103ZET6 最大可达到 72M(超频除外)), 然后进入主函数。那么这个系统时钟大小如何得来,其他外设的时钟又如何划分, 这些问题都可以通过一张时钟树图找到答案,只要理解好时钟树,STM32一切时钟的来龙去脉就会非常清楚。
2.时钟配置函数
均可在固件库中手册查找到,此处介绍几个常用函数
3.自定义系统时钟
主函数如下
#include "stm32f10x.h"
#include "led.h"
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,通过while循环占用CPU,达到延时功能
* 输 入 : i
* 输 出 : 无
*******************************************************************************/
void delay(u32 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : RCC_HSE_Config
* 函数功能 : 自定义系统时钟,可以通过修改PLL时钟源和倍频系数实现时钟调整
* 输 入 : div
pllm
* 输 出 : 无
*******************************************************************************/
void RCC_HSE_Config(u32 div,u32 pllm)//自定义系统时间,可以修改时钟
{
RCC_DeInit();//将外设RCC寄存器重新设置为缺省值,相当于初始化时钟
//在自己定义时钟时加上就可以
RCC_HSEConfig(RCC_HSE_ON);//打开外部高速时钟晶振(HSE)
if(RCC_WaitForHSEStartUp()==SUCCESS)//HSE晶振稳定且就绪
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置AHB时钟,72MHZ
RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速AHB(AHB1)时钟,36MHZ
RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速AHB(AHB2)时钟,72MHZ
RCC_PLLConfig(div,pllm);//设置PLL时钟源以及倍频系数
RCC_PLLCmd(ENABLE);//用于系统时钟,故使能
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);//检查RCC是否就绪
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//选择PLL作为系统时钟
while(RCC_GetSYSCLKSource()!=0X08);//返回用作系统时钟的时钟源 0X08,PLL作为系统时钟
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
int main()
{
RCC_HSE_Config(RCC_PLLSource_HSE_Div2,RCC_PLLMul_7);//28MHZ
//RCC_HSE_Config(RCC_PLLSource_HSE_Div2,RCC_PLLMul_16);//72MHZ,可以将此处注释掉对比
LED_Init();
while(1)
{
GPIO_ResetBits(LED1_PORT,LED1_PIN);//点亮D0
delay(6000000);
GPIO_SetBits(LED1_PORT,LED1_PIN);//熄灭D0
delay(6000000);
GPIO_ResetBits(LED2_PORT,LED2_PIN);//点亮D1
delay(6000000);
GPIO_SetBits(LED2_PORT,LED2_PIN);//熄灭D1
delay(6000000);
}
}
led.c和led.h函数见以下博客