文章目录
前言
本文主要介绍STM32F429的HAL库中的RCC的剩余函数的用法,主要参考资料为:
- Description of STM32F4 HAL and low-layer drivers
- RM0090 Reference manual
本文承接上文<STM32F429第八篇之stm32f4xx_hal_rcc>
本文使用硬件库版本为:
- STM32Cube_FW_F4_V1.11.0
在HAL库中,名称以_ex为后缀的文件表明该文件中的函数并非通用函数,与具体的硬件支持有关。
这部分函数与RCC时钟频率控制相关。
函数
HAL_RCCEx_PeriphCLKConfig
函数原型
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig (RCC_PeriphCLKInitTypeDef * PeriphClkInit)
通过指定参数初始化外设时钟。
注意
- 当使用HAL_RCCEx_PeriphCLKConfig()配置RTC时钟源的时候必须小心,因为此时将会把备份域重置,从而,RTC寄存器和RCC_BDCR寄存器同样会被设置为复位值。
参数
- PeriphClkInit:结构体RCC_PeriphCLKInitTypeDef指针,包含外设时钟的配置信息(I2S, SAI, LTDC, RTC 和 TIM)
返回类型
- HAL_StatusTypeDef :HAL状态定义。
HAL_RCCEx_GetPeriphCLKConfig
函数原型
void HAL_RCCEx_GetPeriphCLKConfig (RCC_PeriphCLKInitTypeDef * PeriphClkInit)
根据RCC配置寄存器的参数来填充RCC_PeriphCLKInitTypeDef。
参数
- PeriphClkInit:指向结构体 RCC_PeriphCLKInitTypeDef的指针。
HAL_RCCEx_GetPeriphCLKFreq
函数模型
uint32_t HAL_RCCEx_GetPeriphCLKFreq (uint32_t PeriphClk)
返回给定的外设时钟频率
注意
- 若函数返回0,则说明该外设时钟参数并不支持此API。
- 并不是所有的硬件都支持此函数,在该版本API中,只有446支持此函数。
参数
- PeriphClk:外设时钟参数可以为:
#define RCC_PERIPHCLK_SAI1 ((uint32_t)0x00000004U)
#define RCC_PERIPHCLK_SAI2 ((uint32_t)0x00000008U)
返回值
- 频率值:单位为kHz。
结构体
HAL_StatusTypeDef
/**
* @brief HAL Status structures definition
*/
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
RCC_PeriphCLKInitTypeDef
typedef struct
{
uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured.
This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */
RCC_PLLI2SInitTypeDef PLLI2S; /*!< PLL I2S structure parameters.
This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */
RCC_PLLSAIInitTypeDef PLLSAI; /*!< PLL SAI structure parameters.
This parameter will be used only when PLLI2S is selected as Clock Source SAI or LTDC */
uint32_t PLLI2SDivQ; /*!< Specifies the PLLI2S division factor for SAI1 clock.
This parameter must be a number between Min_Data = 1 and Max_Data = 32
This parameter will be used only when PLLI2S is selected as Clock Source SAI */
uint32_t PLLSAIDivQ; /*!< Specifies the PLLI2S division factor for SAI1 clock.
This parameter must be a number between Min_Data = 1 and Max_Data = 32
This parameter will be used only when PLLSAI is selected as Clock Source SAI */
uint32_t PLLSAIDivR; /*!< Specifies the PLLSAI division factor for LTDC clock.
This parameter must be one value of @ref RCCEx_PLLSAI_DIVR */
uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection.
This parameter can be a value of @ref RCC_RTC_Clock_Source */
uint8_t TIMPresSelection; /*!< Specifies TIM Clock Prescalers Selection.
This parameter can be a value of @ref RCCEx_TIM_PRescaler_Selection */
#if defined(STM32F469xx) || defined(STM32F479xx)
uint32_t Clk48ClockSelection; /*!< Specifies CK48 Clock Selection this clock used OTG FS, SDIO and RNG clocks.
This parameter can be a value of @ref RCCEx_CK48_Clock_Source */
uint32_t SdioClockSelection; /*!< Specifies SDIO Clock Source Selection.
This parameter can be a value of @ref RCCEx_SDIO_Clock_Source */
#endif /* STM32F469xx || STM32F479xx */
}RCC_PeriphCLKInitTypeDef;
PeriphClockSelection(外设时钟选择)
被配置的时钟选择,可以在以下范围中选择:
/*-------- Peripheral Clock source for STM32F42xxx/STM32F43xxx ---------------*/
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
#define RCC_PERIPHCLK_I2S ((uint32_t)0x00000001U)
#define RCC_PERIPHCLK_SAI_PLLI2S ((uint32_t)0x00000002U)
#define RCC_PERIPHCLK_SAI_PLLSAI ((uint32_t)0x00000004U)
#define RCC_PERIPHCLK_LTDC ((uint32_t)0x00000008U)
#define RCC_PERIPHCLK_TIM ((uint32_t)0x00000010U)
#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000020U)
#define RCC_PERIPHCLK_PLLI2S ((uint32_t)0x00000040U)
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
/*----------------------------------------------------------------------------*/
PLLI2S(PLL I2S 结构体参数)
只有当PLLI2S用作时钟源时,该参数才有效。参数的具体定义如下:
/**
* @brief PLLI2S Clock structure definition
*/
typedef struct
{
uint32_t PLLI2SN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock.
This parameter must be a number between Min_Data = 50 and Max_Data = 432.
This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */
uint32_t PLLI2SR; /*!< Specifies the division factor for I2S clock.
This parameter must be a number between Min_Data = 2 and Max_Data = 7.
This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */
uint32_t PLLI2SQ; /*!< Specifies the division factor for SAI1 clock.
This parameter must be a number between Min_Data = 2 and Max_Data = 15.
This parameter will be used only when PLLI2S is selected as Clock Source SAI */
}RCC_PLLI2SInitTypeDef;
PLLSAI(PLL SAI 结构体参数)
只有当PPLLSAI用作时钟源时,该参数才有效。具体定义如下:
/**
* @brief PLLSAI Clock structure definition
*/
typedef struct
{
uint32_t PLLSAIN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock.
This parameter must be a number between Min_Data = 50 and Max_Data = 432.
This parameter will be used only when PLLSAI is selected as Clock Source SAI or LTDC */
#if defined(STM32F469xx) || defined(STM32F479xx)
uint32_t PLLSAIP; /*!< Specifies division factor for OTG FS and SDIO clocks.
This parameter is only available in STM32F469xx/STM32F479xx devices.
This parameter must be a value of @ref RCCEx_PLLSAIP_Clock_Divider */
#endif /* STM32F469xx || STM32F479xx */
uint32_t PLLSAIQ; /*!< Specifies the division factor for SAI1 clock.
This parameter must be a number between Min_Data = 2 and Max_Data = 15.
This parameter will be used only when PLLSAI is selected as Clock Source SAI or LTDC */
uint32_t PLLSAIR; /*!< specifies the division factor for LTDC clock
This parameter must be a number between Min_Data = 2 and Max_Data = 7.
This parameter will be used only when PLLSAI is selected as Clock Source LTDC */
}RCC_PLLSAIInitTypeDef;
外设时钟管理
这部分内容主要存在于stm32f4xx_hal_rcc.h和stm32f4xx_hal_rcc_ex.h中。通过宏定义的形式,管理外设的时钟。其主要形式如下:
//其中XXX为外设的名称。
#define __HAL_RCC_XXX_CLK_ENABLE() //外设时钟使能
#define __HAL_RCC_XXX_CLK_DISABLE() //外设时钟禁止
#define __HAL_RCC_XXX_IS_CLK_ENABLED() //外设时钟是否使能
#define __HAL_RCC_XXX_IS_CLK_DISABLED() //外设时钟是否禁止
其中,外设时钟使能宏的实现方式相对比较复杂,详细代码如下(以GPIOA外设为例):
#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
UNUSED(tmpreg); \
} while(0)
do{ }while(0)
语句表示该括号中的代码必然执行,且执行的次数为1次。- 定义了
uint32_t
型变量tmpreg
。 - 将 外设对应寄存器位 置1,即使能对应外设的时钟,此语句为该功能的核心语句。
- 将写入的寄存器位读出,且赋值在
tmpreg
变量中。此处,并非真的需要获取寄存器值,而是为了将外设时钟使能后,延时一段时间。 - 因为赋值后的
tmpreg
并未使用,仅仅为了延时作用,所以,最后添加一句UNUSED(tmpreg);
使得编译器在此处不报警告。
时钟被管理的外设是挂载在AHB和APB总线的外设。具体如下:
AHB1
AHB2
AHB3
APB1
APB2
更多详细信息可以参考手册 < RM0090 Reference manual>