打印
[STM32F1]

STM32F1-RCC,Reset&ClockControl

[复制链接]
527|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-4-30 17:10 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
Reset
系统复位
电源复位
备份域复位
Clock Control
三种不同的时钟驱动系统时钟

HSI

HSE

PLL

RCC时钟树



STM32F1推荐SYSYCLK时钟为72MHz,所以各个时钟设置如下:

HSE = 8MHz,AHB = 72MHZ,APB1 = 36MHz,APB2 = 72MHz;
USB = 48Mhz;
HCLK = 72MHz;
Cortex系统时钟(SysTick Clock) = 9Mhz;
PCLK1 = 36MHz
PCLK2 = 72MHz
TIMxCLK = 72MHz
ADCCLK = 12MHz
LSE = 32.768kHz
HSI = 8Mhz
LSI = 40kHz
RCC寄存器

typedef struct
{
  __IO uint32_t CR;
  __IO uint32_t CFGR;
  __IO uint32_t CIR;
  __IO uint32_t APB2RSTR;
  __IO uint32_t APB1RSTR;
  __IO uint32_t AHBENR;
  __IO uint32_t APB2ENR;
  __IO uint32_t APB1ENR;
  __IO uint32_t BDCR;
  __IO uint32_t CSR;
} RCC_TypeDef;


HSE作为时钟来源,经过PLL倍频作为系统时钟

void HSE_SetSysClock(void)
{
        __IO uint32_t HSEStatus = 0;
        /* Resets the RCC clock configuration to the default reset state.*/
        RCC_DeInit();

        /* Enable HSE */  
        RCC_HSEConfig(RCC_HSE_ON);

        /* Wait till HSE is ready*/
        HSEStatus = RCC_WaitForHSEStartUp();
       
        if (HSEStatus == SUCCESS)
        {
                /* Enable Prefetch Buffer */
                FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

                /* Flash 2 wait state */
                // 0:0 < SYSCLK <= 24M
                // 1:24< SYSCLK <= 48M
                // 2:48< SYSCLK <= 72M
                FLASH_SetLatency(FLASH_Latency_2);
         
                /* HCLK = SYSCLK */
                RCC_HCLKConfig(RCC_SYSCLK_Div1);
          
                /* PCLK2 = HCLK */
                RCC_PCLK2Config(RCC_HCLK_Div1);

                /* PCLK1 = HCLK/2 */
                RCC_PCLK1Config(RCC_HCLK_Div2);
                       
                /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
                RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

                /* Enable PLL */
                RCC_PLLCmd(ENABLE);

                /* Wait till PLL is ready */
                while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
                {
                }

                /* Select PLL as system clock source */
                RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

                /* Wait till PLL is used as system clock source */
                while (RCC_GetSYSCLKSource() != 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 */
                while (1)
                {
                }
        }
}



HSI/2作为时钟来源,经过PLL倍频作为系统时钟

#define HSI_STARTUP_TIMEOUT                ((uint16_t)0x0500) /*!< Time out for HSI start up */
void HSI_SetSysClock(void)
{
        __IO uint32_t StartUpCounter = 0,HSIStatus = 0;

        /* Resets the RCC clock configuration to the default reset state.*/
        RCC_DeInit();

        /* Enable HSI */
        RCC_HSICmd(ENABLE);
       
        /* Wait till HSI is ready and if Time out is reached exit */
        do{
                HSIStatus = RCC->CR & RCC_CR_HSIRDY;
                StartUpCounter++;
        }while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
       
        if ((HSIStatus & RCC_CR_HSIRDY) != RESET)
        {
                /* Enable Prefetch Buffer */
                FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

                /* Flash 2 wait state */
                // 0:0 < SYSCLK <= 24M
                // 1:24< SYSCLK <= 48M
                // 2:48< SYSCLK <= 72M
                FLASH_SetLatency(FLASH_Latency_2);

                 /* HCLK = SYSCLK */
                RCC_HCLKConfig(RCC_SYSCLK_Div1);

                /* PCLK2 = HCLK */
                RCC_PCLK2Config(RCC_HCLK_Div1);

                /* PCLK1 = HCLK/2 */
                RCC_PCLK1Config(RCC_HCLK_Div2);
                       
                /*  PLL configuration: PLLCLK = HSI * 16 = 64 MHz */
                RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
                //------------------------------------------------------------------//

                 /* Enable PLL */
                RCC_PLLCmd(ENABLE);

                /* Wait till PLL is ready */
                while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
                {
                }

                /* Select PLL as system clock source */
                RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

                /* Wait till PLL is used as system clock source */
                while (RCC_GetSYSCLKSource() != 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 */
                while (1)
                {
                }
        }
}



MCO时钟输出

RCC MCO硬件相关宏定义,bsp_mco.h

#ifndef __BSP_RCCMCO_H
#define __BSP_RCCMCO_H

#include "stm32f10x.h"

#define BSP_RCC_MCO_Clk             RCC_APB2Periph_GPIOA      
#define BSP_RCC_MCO_Clk_Cmd         RCC_APB2PeriphClockCmd
#define BSP_RCC_MCO_Port            GPIOA
#define BSP_RCC_MCO_Pin             GPIO_Pin_8


#endif /* __BSP_RCCMCO_H */


配置MCO GPIO

static void BSP_MCO_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        BSP_RCC_MCO_Clk_Cmd(BSP_RCC_MCO_Clk, ENABLE);

    GPIO_InitStructure.GPIO_Pin = BSP_RCC_MCO_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BSP_RCC_MCO_Port, &GPIO_InitStructure);
}

void BSP_MCO_Init(void)
{
        BSP_MCO_GPIO_Config();
    //RCC_MCOConfig(RCC_MCO_HSE);                                     
        //RCC_MCOConfig(RCC_MCO_HSI);                           
        //RCC_MCOConfig(RCC_MCO_PLLCLK_Div2);
        RCC_MCOConfig(RCC_MCO_SYSCLK);                     
}




时间安全系统CSS
时钟安全系统可以通过软件被激活。一旦其被激活,时钟监测器将在HSE振荡器启动延迟后被使能,并在HSE时钟关闭后关闭。

void RCC_ClockSecuritySystemCmd(ENABLE);


如果HSE时钟发生故障,HSE振荡器被自动关闭,时钟失效事件将被送到高级定时器(TIM1和TIM8)的刹车输入端,并产生时钟安全中断CSSI,允许软件完成营救操作。此CSSI中断连接到Cortex™-M3的NMI中断(不可屏蔽中断)。

注意: 一旦CSS被激活,并且HSE时钟出现故障,CSS中断就产生,并且NMI也自动产生。NMI将被不断执行,直到CSS中断挂起位被清除。因此,在NMI的处理程序中必须通过设置时钟中断寄存器(RCC_CIR)里的CSSC位来清除CSS中断。

如果HSE振荡器被直接或间接地作为系统时钟,(间接的意思是:它被作为PLL输入时钟,并且PLL时钟被作为系统时钟),时钟故障将导致系统时钟自动切换到HSI振荡器,同时外部HSE振荡器被关闭。在时钟失效时,如果HSE振荡器时钟(被分频或未被分频)是用作系统时钟的PLL的输入时钟,PLL也将被关闭。

void NMI_Handler(void)
{
    if (RCC_GetITStatus(RCC_IT_CSS) != RESET)
    {    // HSE、PLL 已被禁止(但是PLL 设置未变)
         /* …… */ // 客户添加相应的系统保护代码处
        // 下面为HSE恢复后的预设置代码
       RCC_HSEConfig(RCC_HSE_ON);  // 使能HSE
       RCC_ ITConfig(RCC_IT_HSERDY,ENABLE); // 使能HSE就绪中断
       RCC_ ITConfig(RCC_IT_PLLRDY,ENABLE); // 使能PLL 就绪中断
       RCC_ClearITPendingBit(RCC_IT_CSS);  // 清除时钟安全系统中断的挂起位

       // 至此,一旦HSE时钟恢复,将发生HSERDY中断,

       //在RCC中断处理程序里, 系统时钟可以设置到以前的状态
    }
}
void RCC_IRQHandler(void)
{
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

        if(RCC_GetITStatus(RCC_IT_HSERDY) != RESET)
    {
        RCC_ClearITPendingBit(RCC_IT_HSERDY);  // 清除时钟安全系统中断的挂起位
        RCC_DeInit();
        /* Enable HSE */  
        RCC_HSEConfig(RCC_HSE_ON);
        /* Wait till HSE is ready and if Time out is reached exit */
        HSEStatus = RCC_WaitForHSEStartUp();
        if(HSEStatus == SUCCESS)
        {
            FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
            FLASH_SetLatency(FLASH_Latency_2);

            RCC_HCLKConfig(RCC_SYSCLK_Div1);
                 RCC_PCLK1Config(RCC_HCLK_Div2);
                 RCC_PCLK2Config(RCC_HCLK_Div1);
            RCC_PLLConfig(RCC_PLLSource_HSE_Div1,9);
            RCC_PLLCmd(ENABLE);
            /* Wait till HSE is ready */
            while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
            /* SYSCLK is PLLCLK ,nor HSE CLK*/
            RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
            /* Wait till PLL is ready */
            while (RCC_GetSYSCLKSource() != 0x08);
        }
    }
}



mark:由于之前在上一家公司工作对于系统稳定性有很高的要求,所以看到CSS决定写尝试写一下这部分的代码。

上述代码未经过实际工程验证,只是在看完STM32F10x参考手册中关于CSS部分所写。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/ZipingPan/article/details/137313373

使用特权

评论回复
沙发
xixi2017| | 2024-4-30 21:10 | 只看该作者
时钟和复位电路不行,导致的问题是很严重的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1931

主题

15612

帖子

12

粉丝