天天看点

STM32_时钟复位? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。时钟树简图代码学习

STM32时钟学习

  • 复位
    • 编程控制系统复位
  • ? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。
  • 时钟树简图
    • 实际的寄存器操作
      • (1)对RCC_CR寄存器进行设置
      • (2)时钟配置寄存器(RCC_CFGR)
      • (3)RCC PLL configuration register (RCC_PLLCFGR)
      • (4)RCC clock interrupt register (RCC_CIR)
      • (5)RCC AHB1 peripheral reset register (RCC_AHB1RSTR)复位
      • (6)RCC AHB1 peripheral clock register (RCC_AHB1ENR)使能
      • (7)备份域控制寄存器 (RCC_BDCR)
  • 代码学习

f(VCO clock) = f(PLL clock input) × (PLLN / PLLM)

f(PLL general clock output) = f(VCO clock) / PLLP

f(USB OTG FS, SDIO, RNG clock output) = f(VCO clock) / PLLQ

PLLN with 192 ≤ PLLN ≤ 432

PLLM with 2 ≤ PLLM ≤ 63

PLLP = 2, 4, 6, or 8

4 <= PLLQ <= 15

复位

支持三种复位形式,分别为系统复位、上电复位和备份区域复位。

电源复位:除了备份区域外的所有寄存器

系统复位:除了时钟控制器的RCC_CSR寄存器中的复位标志位和备份区域中的寄存器以外的所有寄存器

备份区域复位:只影响备份区域

产生电源复位的事件:

  1. 上电/掉电复位(POR/PDR复位)
  2. 从待机模式中返回

产生备份区域复位的事件:

  1. 软件复位,备份区域复位可由设置备份域控制寄存器 (RCC_BDCR)中的BDRST位产生。
  2. 在VDD和VBAT两者掉电的前提下,VDD或VBAT上电将引发备份区域复位

产生一个系统复位的事件:

  1. NRST引脚上的低电平(外部复位)
  2. 窗口看门狗计数终止(WWDG复位)
  3. 独立看门狗计数终止(IWDG复位)
  4. 软件复位(SW复位)
  5. 低功耗管理复位

编程控制系统复位

我们所能控制的只有系统复位

(1)可通过查看RCC_CSR控制状态寄存器中的复位状态标志位识别复位事件来源。

(2)软件的方式进行系统复位:通过将Cortex™-M3中断应用和复位控制寄存器中的SYSRESETREQ位置’1’

(3)低功耗管理复位

在以下两种情况下可产生低功耗管理复位:

在进入待机模式时产生低功耗管理复位:

通过将用户选择字节中的nRST_STDBY位置’1’将使能该复位。这时,即使执行了进入待

机模式的过程,系统将被复位而不是进入待机模式。

在进入停止模式时产生低功耗管理复位:

通过将用户选择字节中的nRST_STOP位置’1’将使能该复位。这时,即使执行了进入停机

模式的过程,系统将被复位而不是进入停机模式。

? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。

时钟树简图

STM32为了低功耗,将所有的外设时钟都设置为disable。使用外设,需要打开对应时钟。

看图理解时钟源—>系统时钟来源—>各个外设时钟

STM32_时钟复位? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。时钟树简图代码学习

三种不同的时钟源可被用来驱动系统时钟(SYSCLK): HSI振荡器时钟、 HSE振荡器时钟、 PLL时钟(内部PLL可以用来倍频HSI RC的输出时钟或HSE晶体输出时钟)。

这些设备有40kHz低速内部RC、32.768kHz低速外部晶体2种二级时钟源,当不被使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗。

实际的寄存器操作

(1)对RCC_CR寄存器进行设置

Reset value: 0x0000 XX83 where X is undefined.

STM32_时钟复位? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。时钟树简图代码学习

STM32F207支持一种专用的PLL(PLLI2S),用于在I2S接口上生成精确的时钟,以实现高质量的音频性能。

(2)时钟配置寄存器(RCC_CFGR)

Reset value: 0x0000 0000

STM32_时钟复位? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。时钟树简图代码学习

(3)RCC PLL configuration register (RCC_PLLCFGR)

Address offset: 0x04

Reset value: 0x24003010

该寄存器用于根据公式配置锁相环时钟输出

(4)RCC clock interrupt register (RCC_CIR)

(5)RCC AHB1 peripheral reset register (RCC_AHB1RSTR)复位

STM32_时钟复位? 用户选择字节的进一步信息,请参考STM32F10xxx闪存编程手册。时钟树简图代码学习

(6)RCC AHB1 peripheral clock register (RCC_AHB1ENR)使能

当外设时钟没有启用时,软件不能读出外设寄存器的数值,返回的数值始终是0x0。

(7)备份域控制寄存器 (RCC_BDCR)

代码学习

没有打开任何外设时钟的代码学习

或操作开,与操作关

开HSI

关HSE、CSS、PLL

关HSEBYP

开HSE

不同应用下,时钟频率的选择和使用过程中出现误差的一个校准(配置对应寄存器)

系统复位后,HSI振荡器被选为系统时钟。当时钟源被直接或通过PLL间接作为系统时钟时,它将不能被停止。只有当目标时钟源准备就绪了(经过启动稳定阶段的延迟或PLL稳定),从一个时钟源到另一个时钟源的切换才会发生。在被选择时钟源没有就绪时,系统时钟的切换不会发生。直至目标时钟源就绪,才发生切换。在时钟控制寄存器(RCC_CR)里的状态位指示哪个时钟已经准备好了,哪个时钟目前被用作系统时钟。通过设置备份域控制寄存器(RCC_BDCR)里的RTCSEL[1:0]位,RTCCLK时钟源可以由HSE/128、LSE或LSI时钟提供。除非备份域复位,此选择不能被改变。

/*********************************系统初始化*************************************/
	/*            PLL (clocked by HSE) used as System clock source                */
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  /* 其他不变,HSION=1 */
	RCC->CR |= (uint32_t)0x00000001;
  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;
  /* 其他不变,HSEON, CSSON, PLL OFF*/
  RCC->CR &= (uint32_t)0xFEF6FFFF;
  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;
  /*  其他不变,HSEBYP off */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
  /* Disable all interrupts */
  RCC->CIR = 0x00000000;
  /* 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)
  {
    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

    /* Configure the main PLL */
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

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

    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
   
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_3WS;

    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  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 */
  }