stm32F1xx时钟配置分析总结

前言

正如万物的生长、发展离不开时间、节律一样,芯片的工作也离不开时钟的驱动,本文总结stm32f1xx的时钟系统介绍以及时钟配置时的步骤、寄存器操作;

时钟树

在这里插入图片描述
上图为stm32f1xx的参考手册中的时钟树图,图中梯形框表示复用选择,方形框表示倍频或分频或时钟源;

stm32中的时钟包括HSI、HSE、LSI、LSE(内部高速振动器、外部高速振荡器、内部低速振荡器、外部低速振荡器)、PLL(锁相环);

其中HSI、HSE、LSI、LSE 可以直接提供时钟,而PLL需要以HSE、HSI为直接源或者以HSE为源并通过MCU内部分频倍频处理后得到PLL;

sysclk系统时钟也可以直接选择HSI、HSE为源头,不过这些频率都比较小在有PLL模块的芯片一般会使用PLL获得一个高频率作为系统时钟;

系统时钟作为AHB总线的输入时钟源,经过AHB总线分频后的输出作为APB1和APB2的时钟源,在时钟树节点中节点可以以某个时钟为源且可以对源的频率进行分频或者倍频给下一级,直到最终的时钟源使用者;结合以下的系统架构图方便理解:
在这里插入图片描述

配置列举

下面以系统时钟和uart外设时钟为例说明时钟配置

系统时钟

stm32f1xx系列最高主频为72Mhz,以配置为72Mhz说明具体配置过程:
1、时钟配置外设RCC的寄存器如下

typedef struct
{
  __IO uint32_t CR; //时钟控制寄存器,主要对HSE、HSI、PLL的开关控制和状态查询
  __IO uint32_t CFGR; //时钟配置寄存器,对时钟源的选择配置、分频倍频的配置
  __IO uint32_t CIR;  //时钟中断寄存器,用于清除时钟中断标志和包括表示时钟中断的位域
  __IO uint32_t APB2RSTR;  //APB2外设复位寄存器
  __IO uint32_t APB1RSTR;  //APB1外设复位寄存器
  __IO uint32_t AHBENR; //使能AHB上外设的时钟
  __IO uint32_t APB2ENR; //使能APB2上外设的时钟
  __IO uint32_t APB1ENR; //使能APB1上外设的时钟
  __IO uint32_t BDCR;
  __IO uint32_t CSR;

#ifdef STM32F10X_CL  
  __IO uint32_t AHBRSTR;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_CL */ 

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)   
  uint32_t RESERVED0;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */ 
} RCC_TypeDef;

2、配置函数调用过程
Reset_Handler【startup_stm32f10x_hd.s】 -> SystemInit【system_stm32f10x.c】 -> SetSysClock【system_stm32f10x.c】-> SetSysClockTo72【system_stm32f10x.c】 = 产生72Mhz时钟
3、函数说明
SystemInit 中有英文注释可以对照手册的对寄存器的说明进行理解,主要是在进行时钟配置前做一些时钟复位的工作 ;
SetSysClock为一个中间函数会根据目标系统时钟宏选择调用哪个函数,这里调用SetSysClockTo72;
SetSysClock函数为时钟配置主要函数

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* Enable HSE */
  //bit16 使能选择HSE外部高度振荡器,这里为8Mhz    
  RCC->CR |= ((uint32_t)RCC_CR_HSEON); 
  /* Wait till HSE is ready and if Time out is reached exit */
  //查询CR的bit17判断振荡器是否准备好或者有信号
  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) //HSE振荡器正常
  {
    /* Enable Prefetch Buffer */
    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;    
    /* HCLK = SYSCLK */
    //CFGR寄存器的bit7~bit4配置AHB对系统时钟不进行分频
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
    /* PCLK2 = HCLK */
    //CFGR寄存器的bit13~bit11配置APB2对AHB过来的时钟不进行分频
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK */
    //CFGR寄存器的bit10~bit8配置APB1对AHB过来的时钟进行二分频
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL
    
#else    
    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
    //清除bit16:RCC_CFGR_PLLSRC PLL时钟源是HSI
    //清除bit17:RCC_CFGR_PLLXTPRE 对HSE时钟不分频,PREDIV1从时钟树中看到它表示HSE后面的分频器
    //清除bit21~bit18 PLL倍频系数先清0 不倍频
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    
    //配置bit16:RCC_CFGR_PLLSRC_HSE 选择HSE作为PLL的时钟源
    //配置bit21~bit18 对PLL时钟倍频9 得到PLLCLK 为 8Mhz*9=72Mhz
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

    /* Enable PLL */
    //使能CR的bit24 PLL使能
    RCC->CR |= RCC_CR_PLLON;
    /* Wait till PLL is ready */
    //判断bit25 PLL时钟是否锁定
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /* Select PLL as system clock source */
    //清除bit1~bit0,随后设置为0x02表示将PLL作为系统时钟
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* Wait till PLL is used as system clock source */
    //bit3~bit2 判断是否切换为PLL作为系统时钟
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
  }
}

TIMER时钟

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F1xx系列MCU外围元件配置参考数据是指在设计和开发STM32F1xx系列微控制器的应用时,参考使用的外围元件的配置参数。 在配置STM32F1xx系列MCU的外围元件时,需要根据具体的应用需求,选择适当的元件,并配置相应的参数。以下是一些常见的外围元件和配置参数的参考数据: 1. 时钟振荡器(Crystal Oscillator):选择合适的晶体、频率和负载电容,以提供稳定的时钟信号供MCU使用。 2. 复位电路(Reset Circuit):选择合适的复位电路,包括复位按钮、电源-on复位和外部复位信号,以确保系统能够正确复位。 3. 电源管理电路(Power Management Circuit):选择合适的电源管理电路,包括稳压器、电源过滤器和电源监测电路,以确保MCU在稳定的电源供应下正常工作。 4. 外部存储器(External Memory):选择适当的存储器类型(如Flash、SRAM)和容量,以扩展MCU的存储空间。 5. 通信接口(Communication Interface):选择适当的通信接口,如UART、SPI、I2C、CAN等,并配置相应的参数,以实现与外部设备的通信。 6. 中断控制器(Interrupt Controller):配置中断向量表和优先级,以实现中断处理功能。 7. GPIO(General Purpose Input/Output):配置GPIO引脚的输入/输出模式和驱动能力,以适应不同的应用需求。 通过参考这些外围元件的配置参数,可以确保STM32F1xx系列MCU的外围元件能够正常工作,并满足应用的需求。同时,也有助于提高系统的性能和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值