a.可以使用三种不同的时钟源来驱动系统时钟 (SYSCLK),CPU 运行的频率为 168MHz:
HSI 振荡器时钟,也就是高速内部时钟,一般来说很少用,因为精度没有外部高速时钟那么高
HSE 振荡器时钟,也就是高速外部时钟,GECM4开发板8MHz
主PLL (PLL)时钟
b.STM32器件具有以下两个次级时钟源:
32kHz 低速内部 RC(LSI RC),该RC用于驱动独立看门狗,也可选择提供给RTC用于停机/待机模式下的自动唤醒
32.768kHz 低速外部晶振(LSE 晶振),用于驱动RTC时钟(RTCCLK)对于每个时钟来说,在未使用时都可单独单开或者关闭。以降低功耗
ARM 公司推出的 AMBA 片上总线受到了广大 IP 开发商和 SoC 系统集成者的青睐,已成为一种流行的工业标准片上结构。AMBA 规范主要包括了 AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。二者分别适用于高速与相对低速设备的连接。
AHB(Advanced High-performance Bus) 是高级高性能总线,简称高速总线,是一种系统总线,它主要负责连接处理器、DMA 等一些内部接口。AHB 系统由主模块、从模块和基础结构 3 部分组成,整个 AHB 总线上的传输都由主模块发出,由从模块负责回应。
APB(Advanced Peripheral Bus) 高级外围总线,是低速总线,它主要负责连接外围设备,它又分为 APB1 和 APB2,它的总线架构不像 AHB 支持多个主模块,在 APB 里面唯一的主模块就是 APB 桥。APB 桥就是连接 AHB 和 APB 中间的玩意。APB2负责AD,I/O,高级TIM,串口1;APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM。
使用时钟源时由于官方的代码是使用外部高速晶振25MHz,GEC-M4开发板是使用外部高速晶振8MHz,所以PLL的倍频因子要进行修改,只修改PLL_M为8在system_stm32f4xx.c中修改,此外还要修改 stm32f4xx.h的内容,将127行中的外部晶振频率值修改为8MHz。
倍频计算公式:f(VCO时钟) = f(PLL时钟输入)*f(PLL_N/PLL_M);f(PLL常规时钟输出) = f(VCO时钟)/PLL_P;
PLL时钟输入是输出的频率(如8MHz),PLL_N的范围(192,432),PLL_M的范围(2,63),PLL_p=2、4、6、8
时钟源切换
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW))
RCC->CFGR |= RCC_CFGR_SW_x x表示HSI、HSE、PLL
例
#include "stm32f4xx.h"
GPIO_InitTypeDef GPIO_Initstrue;
//初始化LED
void InitLED()
{
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOF
|RCC_AHB1Periph_GPIOE
|RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_Initstrue.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
GPIO_Initstrue.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Initstrue.GPIO_OType = GPIO_OType_PP;
GPIO_Initstrue.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Initstrue.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOF,&GPIO_Initstrue);
GPIO_Initstrue.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
GPIO_Init(GPIOE,&GPIO_Initstrue);
//设置端口A为输入模式
GPIO_Initstrue.GPIO_Pin = GPIO_Pin_0;
GPIO_Initstrue.GPIO_Mode = GPIO_Mode_IN;
GPIO_Initstrue.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Initstrue.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_Initstrue);
GPIO_Initstrue.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_Init(GPIOE,&GPIO_Initstrue);
GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14);
}
void deply(__IO uint32_t count)
{
while(count--);
}
void LED_On()
{
GPIO_ResetBits(GPIOF,GPIO_Pin_9);
deply(0x0FFFFF);
GPIO_SetBits(GPIOF,GPIO_Pin_9);
deply(0x0FFFFF);
GPIO_ResetBits(GPIOF,GPIO_Pin_10);
deply(0x0FFFFF);
GPIO_SetBits(GPIOF,GPIO_Pin_10);
deply(0x0FFFFF);
GPIO_ResetBits(GPIOE,GPIO_Pin_13);
deply(0x0FFFFF);
GPIO_SetBits(GPIOE,GPIO_Pin_13);
deply(0x0FFFFF);
GPIO_ResetBits(GPIOE,GPIO_Pin_14);
deply(0x0FFFFF);
GPIO_SetBits(GPIOE,GPIO_Pin_14);
deply(0x0FFFFF);
}
void led_Off()
{
GPIO_SetBits(GPIOF,GPIO_Pin_9);
GPIO_SetBits(GPIOF,GPIO_Pin_10);
GPIO_SetBits(GPIOE,GPIO_Pin_13);
GPIO_SetBits(GPIOE,GPIO_Pin_14);
}
//循环LED
void LED_cycle()
{
while(1)
{
if(Bit_RESET==GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))
{
//支持 HSI
RCC->CFGR &=(uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_HSI;
LED_On();
}
if(Bit_RESET==GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2))
{
//支持 HSE
RCC->CFGR &=(uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_HSE;
LED_On();
}
if(Bit_RESET==GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3))
{
//支持 PLL
RCC->CFGR &=(uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
LED_On();
}
}
}
int main(void)
{
InitLED();
LED_cycle();
}