[其他ST产品] STM32系统时钟配置

[复制链接]
1077|19
 楼主| 泡椒风爪 发表于 2023-10-28 01:00 | 显示全部楼层 |阅读模式
STM32启动后的第一步对于开发者来说就是系统时钟(RCC)的配置了,STM32系统默认用户外接8M晶振,经过倍频后,系统可以跑到72M。时钟的配置过程或者是初始化过程(当用户不配置时,使用默认外接8M晶振的配置)大体是这样的:
1、在STM32启动文件startup_stm32f10x_md.s的汇编代码中调用SystemInit()函数,而此函数是在system_stm32f10x.c文件中定义的;

注:如果用keil的启动文件,可能不会调用SystemInit()函数,需要自己在程序中调用。

startup_stm32f10x_md.s:

18481653becb28f4b7.png

 楼主| 泡椒风爪 发表于 2023-10-28 01:00 | 显示全部楼层
2、在SystemInit()函数中通过对相关寄存器的一系列配置后,调用了本文件(system_stm32f10x.c)中的SetSysClock()函数

system_stm32f10x.c:
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  Setup the microcontroller system
  3.   *         Initialize the Embedded Flash Interface, the PLL and update the
  4.   *         SystemCoreClock variable.
  5.   * [url=home.php?mod=space&uid=536309]@NOTE[/url]   This function should be used only after reset.
  6.   * @param  None
  7.   * @retval None
  8.   */
  9. void SystemInit (void)
  10. {
  11.     //...省略一部分内容
  12. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
  13.   #ifdef DATA_IN_ExtSRAM
  14.     SystemInit_ExtMemCtl();
  15.   #endif /* DATA_IN_ExtSRAM */
  16. #endif

  17.   /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  18.   /* Configure the Flash Latency cycles and enable prefetch buffer */
  19.   SetSysClock();

  20. #ifdef VECT_TAB_SRAM
  21.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
  22. #else
  23.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
  24. #endif
  25. }
 楼主| 泡椒风爪 发表于 2023-10-28 01:01 | 显示全部楼层
SetSysClock:、
84794653becdc6a8cb.png
 楼主| 泡椒风爪 发表于 2023-10-28 01:01 | 显示全部楼层
在此函数中通过判断之前定义过的宏,来决定调用设置系统不同时钟频率的函数,而这些宏是在此文件前面根据STM32不同的产品来定义的(对于低、中、高密度的产品使用外部8M晶振,对于互联型产品使用外部25M晶振),当然用户可以指定系统运行的速度24M、36M、48M、56M、72M,或自定义HSE_VALUE值,系统默认使用72M;
 楼主| 泡椒风爪 发表于 2023-10-28 01:01 | 显示全部楼层
 楼主| 泡椒风爪 发表于 2023-10-28 01:01 | 显示全部楼层
据第2步所述,系统将在SetSysClock()函数中调用SetSysClockTo72()函数,在SetSysClockTo72()函数中通过一系列对相关寄存器的配置,来完成系统时钟的配置。
 楼主| 泡椒风爪 发表于 2023-10-28 01:02 | 显示全部楼层
SetSysClockTo72:
  1. /**
  2.   * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2
  3.   *         and PCLK1 prescalers.
  4.   * @note   This function should be used only after reset.
  5.   * @param  None
  6.   * @retval None
  7.   */
  8. static void SetSysClockTo72(void)
  9. {
  10.   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  11.   
  12.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   
  13.   /* Enable HSE */   
  14.   RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  15.   /* Wait till HSE is ready and if Time out is reached exit */
  16.   do
  17.   {
  18.     HSEStatus = RCC->CR & RCC_CR_HSERDY;
  19.     StartUpCounter++;  
  20.   } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  21.   if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  22.   {
  23.     HSEStatus = (uint32_t)0x01;
  24.   }
  25.   else
  26.   {
  27.     HSEStatus = (uint32_t)0x00;
  28.   }  

  29.   if (HSEStatus == (uint32_t)0x01)
  30.   {
  31.     /* Enable Prefetch Buffer */
  32.     FLASH->ACR |= FLASH_ACR_PRFTBE;

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


  36.     /* HCLK = SYSCLK */
  37.     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
  38.       
  39.     /* PCLK2 = HCLK */
  40.     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
  41.    
  42.     /* PCLK1 = HCLK */
  43.     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

  44. #ifdef STM32F10X_CL
  45.     /* Configure PLLs ------------------------------------------------------*/
  46.     /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
  47.     /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
  48.         
  49.     RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
  50.                               RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
  51.     RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
  52.                              RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
  53.   
  54.     /* Enable PLL2 */
  55.     RCC->CR |= RCC_CR_PLL2ON;
  56.     /* Wait till PLL2 is ready */
  57.     while((RCC->CR & RCC_CR_PLL2RDY) == 0)
  58.     {
  59.     }
  60.    
  61.    
  62.     /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
  63.     RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
  64.     RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
  65.                             RCC_CFGR_PLLMULL9);
  66. #else   
  67.     /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
  68.     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
  69.                                         RCC_CFGR_PLLMULL));
  70.     RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
  71. #endif /* STM32F10X_CL */

  72.     /* Enable PLL */
  73.     RCC->CR |= RCC_CR_PLLON;

  74.     /* Wait till PLL is ready */
  75.     while((RCC->CR & RCC_CR_PLLRDY) == 0)
  76.     {
  77.     }
  78.    
  79.     /* Select PLL as system clock source */
  80.     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  81.     RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;   

  82.     /* Wait till PLL is used as system clock source */
  83.     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
  84.     {
  85.     }
  86.   }
  87.   else
  88.   { /* If HSE fails to start-up, the application will have wrong clock
  89.          configuration. User can add here some code to deal with this error */
  90.   }
  91. }
 楼主| 泡椒风爪 发表于 2023-10-28 01:02 | 显示全部楼层
/**
  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2
  *         and PCLK1 prescalers.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   
  /* Enable HSE */   
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  /* Wait till HSE is ready and if Time out is reached exit */
  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)
  {
    /* 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 */
    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;

#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
        
    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);
  
    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }
   
   
    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
                            RCC_CFGR_PLLMULL9);
#else   
    /*  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);
#endif /* STM32F10X_CL */

    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
   
    /* Select PLL as system clock source */
    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 */
    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 */
  }
}
 楼主| 泡椒风爪 发表于 2023-10-28 01:02 | 显示全部楼层
备注:
启动文件:
startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xx
startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_hd_vl.s 大容量的STM32F100xx
startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_ld_vl.s 小容量的STM32F100xx
startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_md_vl.s 中容量的STM32F100xx
startup_stm32f10x_xl.s FLASH在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xx
 楼主| 泡椒风爪 发表于 2023-10-28 01:02 | 显示全部楼层
产品分类:
- Low-density Value line devices are STM32F100xx microcontrollers where the
   Flash memory density ranges between 16 and 32 Kbytes.
- Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx
   microcontrollers where the Flash memory density ranges between 16 and 32 Kbytes.
- Medium-density Value line devices are STM32F100xx microcontrollers where
   the Flash memory density ranges between 64 and 128 Kbytes.  
- Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx
   microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes.
- High-density devices are STM32F101xx and STM32F103xx microcontrollers where
   the Flash memory density ranges between 256 and 512 Kbytes.
- XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
   the Flash memory density ranges between 512 and 1024 Kbytes.
- Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
万图 发表于 2023-12-10 07:04 | 显示全部楼层

具存储功能的存储器芯片也能加密
Uriah 发表于 2023-12-10 08:07 | 显示全部楼层

紫外光复位保护电路是不行的
帛灿灿 发表于 2023-12-10 10:03 | 显示全部楼层

大部分能够读取或者识别Flash上的数据就能够获得Firmware文件
Bblythe 发表于 2023-12-10 11:06 | 显示全部楼层

微探针技术都属于侵入型攻击
童雨竹 发表于 2023-12-10 13:02 | 显示全部楼层

如果在编程时加密锁定位被使能/锁定,就无法用普通编程器直接读取单片机内的程序
Pulitzer 发表于 2023-12-10 14:05 | 显示全部楼层

编程器定位插字节
公羊子丹 发表于 2023-12-10 15:08 | 显示全部楼层

单片机一般都有内部程序区和数据区
公羊子丹 发表于 2023-12-10 16:01 | 显示全部楼层

缩短距离较近的电容的寿命
Wordsworth 发表于 2023-12-10 17:04 | 显示全部楼层

利用协议、加密算法或这些算法中的安全漏洞来进行攻击
Clyde011 发表于 2023-12-10 18:07 | 显示全部楼层

CPLD解密,DSP解密都习惯称为单片机解密
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

307

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部