32单片机 时钟 HSE配置系统时钟(五)

时钟树:
在这里插入图片描述HSE OSC(8M)——PLLSRC——PLLMUL(倍频*9=72M)——PLLCLK——SYSCLK(72M)—— AHB预分频(*1)——APB1(*1/2=36M)——PCLK1
可根据不同外设情况配置不同的时钟
//相关图片来自STM32F10x-中文参考手册

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
系统时钟默认为72MHz

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  //SYSCLK, HCLK, PCLK2 and PCLK1 configuration     
  //使能HSE  位16  
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
  //等待HSE就绪,并作超时处理  位17
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

 //再次判断
  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }  

//如果HSE启动成功,则程序继续往下执行
  if (HSEStatus == (uint32_t)0x01)
  
    FLASH->ACR |= FLASH_ACR_PRFTBE; //预缓冲使能

    /* Flash 2 wait state */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
    // HCLK = SYSCLK =72M
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    //PCLK2 = HCLK =72M
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
    // PCLK1 = HCLK =36M

    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
   //锁相环配置 PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz   16-21位
    
    RCC->CR |= RCC_CR_PLLON;
   //使能PPL  24位
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    //判断是否置1  25位
    {
    }  
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
    //选择PPL作为系统时钟
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    //等待PPL切换为系统时钟
    {
    }
  }
  else  //如果HSE启动失败,在此添加代码
  { 
  }
}
#endif

使用HSE配置系统时钟
可以通过控制HSE_SetSysCLK(uint32_t RCC_PLLMul_x)中x的值来控制灯的亮灭快慢

rccclkconfig.c

#include "rccclkconfig.h"
#include "stm32f10x.h"

void HSE_SetSysCLK(uint32_t RCC_PLLMul_x)
{
	ErrorStatus HSEStatus;  //typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;定义需放在函数最前面
	
	RCC_DeInit();                           //复位
	RCC_HSEConfig(RCC_HSE_ON);              //使能HSE
  HSEStatus=RCC_WaitForHSEStartUp();      // 等待HSE就绪
	
	if(HSEStatus==SUCCESS)
	{
	   FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);      //使能欲取指
		 FLASH_SetLatency(FLASH_Latency_2);                         // 72M配置成2个等待
		
		 RCC_HCLKConfig(RCC_SYSCLK_Div1);   //HCLK一分频
     RCC_PCLK1Config(RCC_HCLK_Div2);    //PCLK1二分频
     RCC_PCLK2Config(RCC_HCLK_Div1);    //PCLK2一分频
		
		 RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x);   //锁相环配置
     RCC_PLLCmd(ENABLE);                                   //使能
		
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);      //等待PLL稳定
		
	  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);             //选择系统时钟
		
		while(RCC_GetSYSCLKSource()!=0x08);
	}
	
	else
	{
	}	
}

rccclkconfig.h

#ifndef _RCCCLKCONFIG_H
#define _RCCCLKCONFIG_H

#include "stm32f10x.h"

void HSE_SetSysCLK(uint32_t RCC_PLLMul_x);

#endif

主函数

#include "bsp-led2.h"
#include "stm32f10x.h"
#include "delay.h"
#include "rccclkconfig.h"
 
int main(void)
{	  
  LED_GPIO_Config(); 		        //LED端口初始化
	delay_init(); 		            //初始化延迟函数
  HSE_SetSysCLK(RCC_PLLMul_9);	//初始化RCC函数

	
	while(1)
	{
		 	PBout(5)=0;					     
		  delay_ms(500);
		  PBout(5)=1;					      
		  delay_ms(500);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值