运动控制器34:STM32的复位与时钟及库函数

复位

系统复位

系统复位有5个来源

  1. NRST引脚的低电平
  2. IWDG
  3. WWDG
  4. 软件复位SW
  5. 低功耗管理复位
    如果设置了nRST_STDBY和nRST_STOP=1,则进入待机和停止模式时,将产生复位。
    • 在进入待机模式时产生复位
    • 进入停止模式时产生复位
      可以通过查看寄存器来知道复位的来源

电源复位

产生电源复位可能是上电和掉电,POR/PDR或者是从待机模式返回,芯片内部有一个20us的脉冲发出,此时可以保证芯片的复位。

备份域复位

备份区域的复位只影响备份区域,可以通过软件,或者VDD和VBAT两者都掉电的时候进行复位,这就是为什么要进行备份重启时,我们要取掉电池。

时钟

  • 三种时钟可以驱动系统时钟,HSE,HSI和PLL,内部有一个40KHZ的RC,用来保证看门狗的时钟RTC,RTC在停机后的自动唤醒。另外驱动RTC的时钟也可以选择内部的32.768KHZ的时钟。
  • 简单来说,外部的高速时钟就是晶振,低速时钟是32.768时钟,而内部的高速时钟是8M,低速时钟是40KHZ。


    运动控制器34:STM32的复位与时钟及库函数_第1张图片
    RCC1.png

HSE时钟

外部高速时钟可以直接输入时钟,或者用晶振产生。

HSI时钟

时钟的精度不够,并且最大只有64M,不太推荐使用。

PLL

如果要用到USB接口,时钟必须设置为48M或者72M,可以优先选择72M

LSE

32.768KHZ的时钟,启动以后,要等待释放信号再进行下一步,和上面的晶振的要求一样。也可以用外部的32.768来提供,此时为旁路模式。

LSI

内部的低速时钟主要用于产生低功耗,在停机和待机模式下运行,提供看门狗和唤醒时钟。所有的内部时钟都有一个校准,可以用TIM5来进行校准。

系统时钟选择

系统复位后,HSI被选择为系统时钟,这个时候如果我们用到了HSE,需要进行切换。

时钟安全系统

如果系统出现故障,比如外部时钟坏了,此时首先关闭高级定时器的刹车,放置出现烧毁器件,同时将外部时钟通道关闭,并自动的切换到内部时钟。

RTC时钟

RTC是重要的时钟源,可以有三个来源,内部40K,外部32.768K和外部高速时钟的分频。

  • 32.768时钟时,重要电池还可以用,RTC都会运行
  • 内部40K,此时VDD如果没电,不能保证提供。
  • 外部高速时钟分频:当然不工作啦。

看门狗时钟

如果看门狗启动,40K的时钟强制打开。

时钟输出

如果设置为72M,相当于可以通过GPIO给外面输出:

  • 72M
  • 晶振时钟
  • 8M
  • PLL/2时钟

我们先来看一个典型的时钟配置的程序调用。

  1. 在MAIN函数中,最先调用BSP_Init
  2. 在BSP中,最先进行SystemInit
  3. 系统初始化函数中,调用了SetSysClock函数,里面根据不同的SYSCLK_FREQ_HSE调用了SetSysClockToHSE();
  4. 如果调用的是SetSysClockTo72,将时钟设置为72M

时钟都在system_stm32f10x.h里面进行了设置,标准的RCC库函数还有如下的函数可以使用:另外,还需要特别注意一下的符号的意义:

  • PCLK1 最大36,APB1的时钟
  • PCLK2 最大72M,APB2的时钟
  • HCLK 提供给外设的时钟,最大72M
  • SYSCLK 经AHB分频以后给HCLK,最大为72M

ADC时钟配置:ADCCLKConfig

分频设置

AdjustHSICalibrationValue

内部高速时钟校准,内部时钟不准。

AHBPeriphClockCmd

外设时钟设置,其中APB1PeriphClockCmd 和 APB2包括了哪些外设,要稍微留意一下。

备份寄存器复位:BackupResetCmd

清复位源的标志:ClearFlag

清中断ClearITPendingBit

如果设置时钟的中断, 比如:RCC_IT_LSIRDY: LSI ready interrupt

安全系统开启:ClockSecuritySystemCmd

去初始化DeInit

获取时钟频率GetClocksFreq

包括ADC,HCLK,PCLK1,PCLK2,SYSCLK

GetFlagStatus

GetITStatus

获取系统时钟源GetSYSCLKSource

HCLKConfig

也就是SYSCLK到HCLK的分频

HSEConfig LSEConfig

旁路还是用晶振

HSICmd LSICmd

内部8M是否使能

ITConfig

时钟输出:MCOConfig

PCLK1Config 外设时钟设置

PLLCmd PLL是否使能 PLLConfig

RTCCLKConfig RTCCLKCmd

三个时钟源

SYSCLKConfig 系统时钟

USBCLKConfig

WaitForHSEStartUp 等待晶振稳定

我们为了防止晶振坏了而导致系统直接挂调,可以设置一个RCC_USEHSI,再一次强调,此时钟又慢又不准!

void RCC_USEHSI(void)
{
    GPIO_InitTypeDef X;

    //PD0 PD1分配时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE );  //对端口D分配APB2高速时钟,并开启端口    重映射OSC_IN(PD0) OSC_OUT(PD1)

    //PD0_OSC_IN
    X.GPIO_Pin = GPIO_Pin_0;            //对要使用的端口引脚设定
    X.GPIO_Mode = GPIO_Mode_Out_PP;     //对要使用的端口引脚模式设定PP为推挽输出
    X.GPIO_Speed = GPIO_Speed_50MHz;    //对要使用的端口引脚频率设定50MHz
    GPIO_Init(GPIOD, &X);               //初始化GPIOD寄存器
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE );  //对端口D分配APB2高速时钟,并开启端口
    
    //PD1_OSC_OUT
    X.GPIO_Pin = GPIO_Pin_1;            //对要使用的端口引脚设定
    X.GPIO_Mode = GPIO_Mode_Out_PP;     //对要使用的端口引脚模式设定PP为推挽输出
    X.GPIO_Speed = GPIO_Speed_50MHz;    //对要使用的端口引脚频率设定50MHz
    GPIO_Init(GPIOD, &X);               //初始化GPIOD寄存器

    GPIO_ResetBits(GPIOD, GPIO_Pin_0);      //OSC_IN
    GPIO_ResetBits(GPIOD, GPIO_Pin_1);      //OSC_OUT
        
    GPIO_PinRemapConfig(GPIO_Remap_PD01, ENABLE);           //重映射OSC_IN OSC_OUT

    RCC_DeInit();                       //将外设 RCC寄存器重设为缺省值 
    RCC_HSICmd(ENABLE);                 //使能或者失能内部高速晶振(HSI) 
    while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){}      //HSI 晶振就绪    HSI内部晶振 HSE外部晶振
    
    if(1)      //始终执行,方便关闭,内部时钟设置
    {
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);       //使能预取指缓存
        FLASH_SetLatency(FLASH_Latency_2);          //设置代码延时值为2个延时周期 
        RCC_HCLKConfig(RCC_SYSCLK_Div1);            //设置 AHB 时钟(HCLK)
        RCC_PCLK1Config(RCC_HCLK_Div2);             //设置低速 AHB 时钟(PCLK1)
        RCC_PCLK2Config(RCC_HCLK_Div1);             //设置高速 AHB 时钟(PCLK2)
        RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_2);     //设置 PLL 时钟源及倍频系数
        RCC_PLLCmd(ENABLE);//如果PLL被用于系统时钟,那么它不能被失能    //使能或者失能 PLL,这个参数可以取:ENABLE或者DISABLE
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}     //等待指定的 RCC 标志位设置成功 等待PLL初始化成功
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  //设置系统时钟(SYSCLK)设置PLL为系统时钟源
        while(RCC_GetSYSCLKSource() != 0x08){}      //等待PLL成功用作于系统时钟的时钟源
    }
}

你可能感兴趣的:(运动控制器34:STM32的复位与时钟及库函数)