美文网首页我爱编程
运动控制器34:STM32的复位与时钟及库函数

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

作者: 吴松乾 | 来源:发表于2018-02-02 19:15 被阅读0次

    复位

    系统复位

    系统复位有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。


      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的复位与时钟及库函数

        本文链接:https://www.haomeiwen.com/subject/wpnezxtx.html