9.RCC模块

标准库中有很多模块。我们就一个模块一个模块的分析。慢慢看懂就可以了。

其实看几个就会明白。基本上的套路都是一样的。

RCC模块、时钟

stm32f10x_rcc.c

stm32f10x_rcc.h

我们都知道在单片机中,时钟是不可缺少的。

分析RCC之前我们先简单的说下如何通过起始文件调用时钟的,复制代码:

Reset_Handler            PROC
          EXPORT  Reset_Handler            [WEAK]
          IMPORT   __main
          IMPORT   SystemInit
          LDR R0,   =SystemInit
          BLX R0
          LDR R0, = __main
          BX R0
          ENDP

这是启始文件中的一段代码,会汇编语言编写:大概就是,Reset_Handler            PROC    复位中断   程序

这是一个复位中断,复位中断之后,分别import导入 __main,SystemInit,跳入SystemInit,__main...启始文件就是这样跳入C的世界的。

但是在跳入C之前有LDR R0, =SystemInit   先进入了SystemInit,我们通过查找可以知道。在文件System_stm32f10x.c中,void SystemInit (void){.....}函数

这个函数是通过之前创建工程时的宏定义STM32F10X_HD判断,最后会用的是72M时钟。配置完时钟之后,在调入main中,所以说要是对时钟没有特殊要求,就不用更改时钟,就用默认的72M就可以了。

时钟模块中其实讲了很多东西。我们就慢慢分析下吧。

stm32f10x_rcc.c文件

我们打开stm32f10x_rcc.c文件首先看到的是

/* -------------------------------------------------------------------- RCC registers bit address in the alias region -------------------------------------------------------------- */
#define         RCC_OFFSET              (RCC_BASE - PERIPH_BASE)                                                 //bitband, RCC registers 位段基地址

/* ---------- CR Register ----------*/                      //配置CR寄存器

 

/* Alias word address of HSION bit */     //HSION位
#define   CR_OFFSET                (RCC_OFFSET + 0x00)               //RCC中的CR寄存器的位段地址            


#define   HSION_BitNumber        0x00                                           //HSION在CR寄存器中的0位
#define   CR_HSION_BB            (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4))                //根据公式对应出BB(bitband)地址

/* Alias word address of PLLON bit */
#define   PLLON_BitNumber       0x18                  //0x18     PLLON在寄存器中的24位
#define   CR_PLLON_BB           (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4))

#ifdef STM32F10X_CL                                  //这个是CL的芯片.....如果定义了STM32F10X_CL
/* Alias word address of PLL2ON bit */
#define PLL2ON_BitNumber 0x1A
#define CR_PLL2ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL2ON_BitNumber * 4))

/* Alias word address of PLL3ON bit */
#define PLL3ON_BitNumber 0x1C
#define CR_PLL3ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL3ON_BitNumber * 4))
#endif /* STM32F10X_CL */

/* Alias word address of CSSON bit */
#define CSSON_BitNumber 0x13
#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4))

/* --- CFGR Register ---*/                                                      //RCC中的CFGR寄存器

/* Alias word address of USBPRE bit */
#define CFGR_OFFSET (RCC_OFFSET + 0x04)               //RCC中的CR寄存器的位段地址  ----基地址加上偏移量

#ifndef STM32F10X_CL                                                            //如果没有预定义STM32F10X_CL   
#define USBPRE_BitNumber                0x16
#define CFGR_USBPRE_BB               (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (USBPRE_BitNumber * 4))
#else
#define     OTGFSPRE_BitNumber          0x16
#define     CFGR_OTGFSPRE_BB          (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (OTGFSPRE_BitNumber * 4))
#endif /* STM32F10X_CL */

一直到200多行一直都是按这样的方法进行预定义,查手册就可以看出,固件库把一个可用的位,先按名字预定义了,为了用户方便使用。

在.C文件中宏定义,一般都是在这个.C文件中使用的。在.h中的宏定义,是为了方便外部调用的。

 接下来就是函数了

/**
* @brief Resets the RCC clock configuration to the default reset state.
* @param None
* @retval None
*/
void RCC_DeInit(void){}    //恢复默认配置状态

/**
* @brief Configures the External High Speed oscillator (HSE).
* @note HSE can not be stopped if it is used directly or through the PLL as system clock.
* @param RCC_HSE: specifies the new state of the HSE.
* This parameter can be one of the following values:
* @arg RCC_HSE_OFF: HSE oscillator OFF
* @arg RCC_HSE_ON: HSE oscillator ON
* @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock
* @retval None
*/
void RCC_HSEConfig(uint32_t RCC_HSE){}     //配置HSE

/**
* @brief Waits for HSE start-up.
* @param None
* @retval An ErrorStatus enumuration value:
* - SUCCESS: HSE oscillator is stable and ready to use
* - ERROR: HSE oscillator not yet ready
*/
ErrorStatus RCC_WaitForHSEStartUp(void){}    //等待HSE启动,外部高速时钟 ,可以返回是否成功ErrorStatus,一个枚举类型

有很多函数

打开外设时钟,函数

/**
* @brief Enables or disables the High Speed APB (APB2) peripheral clock.
* @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
* This parameter can be any combination of the following values:
* @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
* RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
* RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
* RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
* RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
* RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
* RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11
* @param NewState: new state of the specified peripheral clock.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState){}  //使能APB2

/**
* @brief Enables or disables the Low Speed APB (APB1) peripheral clock.
* @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
* This parameter can be any combination of the following values:
* @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4,
* RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7,
* RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3,
* RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4,
* RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2,
* RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP,
* RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC,
* RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14
* @param NewState: new state of the specified peripheral clock.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState){}

RCC启动时钟,系统时钟里已经帮我们配置好了。

我们实际应用中,打开外设库,修改时钟就可以了。

需要时查看函数声明。

原文地址:https://www.cnblogs.com/qq376142178/p/12701678.html