STM32F103C8T6_3:启动文件

一、知识所限(以后学习再进一步整理)

/*
在头文件#include "stm32f10x.h"中选择了预处理指令USE_STDPERIPH_DRIVER,STM32F10X_MD
所以在启动文件system_stm32f10x.c中选择系统频率为72MHz
*/
#define SYSCLK_FREQ_72MHz  72000000

//中断向量不偏移
#define VECT_TAB_OFFSET  0x0

//时钟的定义:系统时钟频率(核心时钟)
#elif defined SYSCLK_FREQ_72MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz; 

__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};

static void SetSysClock(void);

#elif defined SYSCLK_FREQ_72MHz
  static void SetSysClockTo72(void);

#ifdef DATA_IN_ExtSRAM
  static void SystemInit_ExtMemCtl(void); 
#endif 

void SystemInit (void)
{
//将RCC时钟配置重置为默认重置状态(用于调试目的)
//设置HSION位
    RCC->CR |= (uint32_t)0x00000001;
//复位SW, HPRE, PPRE1, PPRE2, ADCPRE和MCO位
    RCC->CFGR &= (uint32_t)0xF0FF0000;
//重置HSEON, CSSON和PLLON位
    RCC->CR &= (uint32_t)0xFEF6FFFF;
//重置HSEBYP位
    RCC->CR &= (uint32_t)0xFFFBFFFF;
//复位PLLSRC, PLLXTPRE, PLLMUL和USBPRE/OTGFSPRE位
    RCC->CFGR &= (uint32_t)0xFF80FFFF;
//禁用所有中断并清除挂起的位
    RCC->CIR = 0x009F0000;
/*
配置系统时钟频率、HCLK、PCLK2和PCLK1预分频器;
配置Flash Latency周期,并开启预取缓冲。
*/
    SetSysClock();
#ifdef VECT_TAB_SRAM
//内部SRAM中的矢量表重定位。
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; 
#else
//在内部FLASH矢量表重定位
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
#endif 

}

/*
根据时钟寄存器值更新SystemCoreClock变量。SystemCoreClock变量包含核心时钟(HCLK),它可以
由用户应用程序用来设置SysTick定时器或配置其他参数。

每次核心时钟(HCLK)改变时,必须调用这个函数更新SystemCoreClock变量值。否则,任何配置
基于此变量的将不正确。

由该函数计算出的系统频率不是真实的频率在芯片中。根据预定义值计算常数和所选时钟源:
如果SYSCLK source是HSI, SystemCoreClock将包含HSI_VALUE
如果SYSCLK source为HSE, SystemCoreClock将包含HSE_VALUE
如果SYSCLK源是PLL, SystemCoreClock将包含HSE_VALUE或HSI_VALUE乘以锁相环因子。

HSI_VALUE是stm32f1xx.h文件中定义的常量(默认值8mhz),但实际值可能会根据变化而变化电压和温度。
*/

void SystemCoreClockUpdate (void)
{
  uint32_t tmp = 0, pllmull = 0, pllsource = 0;
//获取SYSCLK源
  tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
  {
//HSI作为系统时钟
    case 0x00: 
      SystemCoreClock = HSI_VALUE;
      break;
//HSE作为系统时钟
    case 0x04:  
      SystemCoreClock = HSE_VALUE;
      break;
//锁相环作为系统时钟
    case 0x08:  
//获得锁相环时钟源和乘法事实
      pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
      pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
      break;

    default:
      SystemCoreClock = HSI_VALUE;
      break;
  }
//计算HCLK时钟频率,获取HCLK预分频器
 tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
//HCLK时钟频率
 SystemCoreClock >>= tmp;
  
}

//配置系统时钟频率、HCLK、PCLK2和PCLK1预分频器。
static void SetSysClock(void)
{
#elif defined SYSCLK_FREQ_72MHz
  SetSysClockTo72();
//如果上述定义均未启用,则使用HSI作为系统时钟源(重置后的默认值)
}

二、时钟配置

        选择外部高速时钟HSE :8M,选择PLL为系统时钟:PLL=9*HSE=72M;APB:72M;APB1:36M;APB2:72M 。       

#elif defined SYSCLK_FREQ_72MHz
//设置系统时钟频率为72MHz,并配置HCLK、PCLK2和PCLK1预压器。

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 
   
//开启HSE 
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
//等待,直到HSE准备好,如果超时到达出口  
  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;
  }  

  if (HSEStatus == (uint32_t)0x01)
  {

//启用预取缓冲区
    FLASH->ACR |= FLASH_ACR_PRFTBE;

// Flash 2等待状态    
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;  
// HCLK = SYSCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
// PCLK2 = HCLK 
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
// PCLK1 = HCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

//   /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
// 开启PLL  
    RCC->CR |= RCC_CR_PLLON;

// 等到锁相环准备好   
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
// 选择“PLL”作为系统时钟源   
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

// 等到锁相环作为系统时钟源    
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else
  {
//如果HSE启动失败,应用程序将出现错误时钟配置。用户可以在这里添加一些代码来处理此错误 
  }
}


  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值