📄 stm32f10x_rcc.c
字号:
/**
******************************************************************************
* @文件 stm32f10x_rcc.c
* @作者 MCD 应用程序组
* @版本 V3.1.0
* @日期 06/19/2009
* @brief 这个文件 提供所有 RCC 固件函数.
* @翻译 ANSON/sweet1985 Email:airanson110@126.com
* @日期 03/07/2009
******************************************************************************
* @复件
*
* 这个固件仅仅是提供给客户作为设计产品而编写程序的参考目的使客户节约时间。由于
* 客户使用本固件在开发产品编程上产生的结果意法半导体公司不承担任何直接的和间接
* 的责任,也不承担任何损害而引起的赔偿。
*
* <h2><center>&复制; 版权所有 2009 意法半导体公司</center></h2>
* 翻译版本仅供学习,如与英文原版有出入应以英文原版为准。
*/
/* 包含 ------------------------------------------------------------------*/
#include "stm32f10x_rcc.h"
/* 自用类型 --------------------------------------------------------------*/
/* 自用定义 --------------------------------------------------------------*/
/* ------------ RCC registers bit address in the alias region ----------- */
#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
/* --- CR 寄存器 ---*/
/* Alias word address of HSION bit */
#define CR_OFFSET (RCC_OFFSET + 0x00)
#define HSION_BitNumber 0x00
#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4))
/* Alias word address of PLLON bit */
#define PLLON_BitNumber 0x18
#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4))
#ifdef 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 寄存器 ---*/
/* Alias word address of USBPRE bit */
#define CFGR_OFFSET (RCC_OFFSET + 0x04)
#ifndef 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 */
/* --- BDCR 寄存器 ---*/
/* Alias word address of RTCEN bit */
#define BDCR_OFFSET (RCC_OFFSET + 0x20)
#define RTCEN_BitNumber 0x0F
#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4))
/* Alias word address of BDRST bit */
#define BDRST_BitNumber 0x10
#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4))
/* --- CSR 寄存器 ---*/
/* Alias word address of LSION bit */
#define CSR_OFFSET (RCC_OFFSET + 0x24)
#define LSION_BitNumber 0x00
#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4))
#ifdef STM32F10X_CL
/* --- CFGR2 寄存器 ---*/
/* Alias word address of I2S2SRC bit */
#define CFGR2_OFFSET (RCC_OFFSET + 0x2C)
#define I2S2SRC_BitNumber 0x11
#define CFGR2_I2S2SRC_BB (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S2SRC_BitNumber * 4))
/* Alias word address of I2S3SRC bit */
#define I2S3SRC_BitNumber 0x12
#define CFGR2_I2S3SRC_BB (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S3SRC_BitNumber * 4))
#endif /* STM32F10X_CL */
/* ---------------------- RCC 寄存器 bit mask ------------------------ */
/* CR register bit mask */
#define CR_HSEBYP_Reset ((uint32_t)0xFFFBFFFF)
#define CR_HSEBYP_Set ((uint32_t)0x00040000)
#define CR_HSEON_Reset ((uint32_t)0xFFFEFFFF)
#define CR_HSEON_Set ((uint32_t)0x00010000)
#define CR_HSITRIM_Mask ((uint32_t)0xFFFFFF07)
/* CFGR register bit mask */
#ifndef STM32F10X_CL
#define CFGR_PLL_Mask ((uint32_t)0xFFC0FFFF)
#else
#define CFGR_PLL_Mask ((uint32_t)0xFFC2FFFF)
#endif /* STM32F10X_CL */
#define CFGR_PLLMull_Mask ((uint32_t)0x003C0000)
#define CFGR_PLLSRC_Mask ((uint32_t)0x00010000)
#define CFGR_PLLXTPRE_Mask ((uint32_t)0x00020000)
#define CFGR_SWS_Mask ((uint32_t)0x0000000C)
#define CFGR_SW_Mask ((uint32_t)0xFFFFFFFC)
#define CFGR_HPRE_Reset_Mask ((uint32_t)0xFFFFFF0F)
#define CFGR_HPRE_Set_Mask ((uint32_t)0x000000F0)
#define CFGR_PPRE1_Reset_Mask ((uint32_t)0xFFFFF8FF)
#define CFGR_PPRE1_Set_Mask ((uint32_t)0x00000700)
#define CFGR_PPRE2_Reset_Mask ((uint32_t)0xFFFFC7FF)
#define CFGR_PPRE2_Set_Mask ((uint32_t)0x00003800)
#define CFGR_ADCPRE_Reset_Mask ((uint32_t)0xFFFF3FFF)
#define CFGR_ADCPRE_Set_Mask ((uint32_t)0x0000C000)
/* CSR register bit mask */
#define CSR_RMVF_Set ((uint32_t)0x01000000)
#ifdef STM32F10X_CL
/* CFGR2 register bit mask */
#define CFGR2_PREDIV1SRC ((uint32_t)0x00010000)
#define CFGR2_PREDIV1 ((uint32_t)0x0000000F)
#define CFGR2_PREDIV2 ((uint32_t)0x000000F0)
#define CFGR2_PLL2MUL ((uint32_t)0x00000F00)
#define CFGR2_PLL3MUL ((uint32_t)0x0000F000)
#endif /* STM32F10X_CL */
/* RCC Flag Mask */
#define FLAG_Mask ((uint8_t)0x1F)
#ifndef HSI_Value
/* Typical Value of the HSI in Hz */
#define HSI_Value ((uint32_t)8000000)
#endif /* HSI_Value */
/* CIR register byte 2 (Bits[15:8]) base address */
#define CIR_BYTE2_ADDRESS ((uint32_t)0x40021009)
/* CIR register byte 3 (Bits[23:16]) base address */
#define CIR_BYTE3_ADDRESS ((uint32_t)0x4002100A)
/* CFGR register byte 4 (Bits[31:24]) base address */
#define CFGR_BYTE4_ADDRESS ((uint32_t)0x40021007)
/* BDCR register base address */
#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET)
#ifndef HSEStartUp_TimeOut
/* Time out for HSE start up */
#define HSEStartUp_TimeOut ((uint16_t)0x0500)
#endif /* HSEStartUp_TimeOut */
/* 自用宏 ------------------------------------------------------------*/
/* 自用变量 ----------------------------------------------------------*/
static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
/* 自用函数原型 ------------------------------------------------------*/
/* 自用函数 ----------------------------------------------------------*/
/**
* @简述 将外设RCC寄存器重设为缺省值.
* @参数 没有
* @返回 没有
*/
void RCC_DeInit(void)
{
/* 置位HSION (内部<8MHz>高速时钟使能) */
RCC->CR |= (uint32_t)0x00000001;
/* 复位 SW, HPRE, PPRE1, PPRE2, ADCPRE , MCO 位 */
/* (HIS被选作系统时钟,HSI振荡器被用作系统时钟,SYSCLK未被分频,HCLK未被分频,
ADC预分频器<PLCK2>被2分频,HSI振荡器时钟/2被选作PLL输入时钟),微控制器无时钟输出 */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000; /* ?在保留区置1 */
#else
RCC->CFGR &= (uint32_t)0xF0FF0000; /* ?在保留区清0 */
#endif /* STM32F10X_CL */
/* 复位 HSEON, CSSON, PLLON 位 (PLL禁用,时钟检测器禁用,HSE振荡器禁用) */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* 复位 HSEBYP 位 (外部1~25MHz振荡器未被旁路) */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* 复位 PLLSRC, PLLXTPRE, PLLMUL , USBPRE/OTGFSPRE 位 */
/*(USB预分频器为PLL时钟1.5分频,PLL倍频参数X2,HSE未被分频作为PLL输入,HSI振荡器时钟/2被当作PLL输入) */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifndef STM32F10X_CL
/* 使所有时钟中断失能 */
RCC->CIR = 0x009F0000;
#else
/* 复位 PLL2ON , PLL3ON 位 () */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* 使所有时钟中断失能 */
RCC->CIR = 0x00FF0000;
/* 复位 CFGR2 寄存器 */
RCC->CFGR2 = 0x00000000;
#endif /* STM32F10X_CL */
}
/**
* @简述 配置外部高速振荡器 (HSE).
* @注解 如果 HSE 被直接使用或者通过 PLL 作为系统时钟,则它不能停止.
* @参数 RCC_HSE: 指定 HSE 新的状态.
* 这个参数可以选择下面的一项:
* RCC_HSE_OFF: HSE 振荡器 OFF
* RCC_HSE_ON : HSE 振荡器 ON
* RCC_HSE_Bypass: HSE 振荡器旁路使用外部时钟
* @返回 没有
*/
void RCC_HSEConfig(uint32_t RCC_HSE)
{
/* 检查参数 */
assert_param(IS_RCC_HSE(RCC_HSE));
/* 复位 HSEON , HSEBYP 位 在配置 HSE 以前 ------------------*/
/* Reset HSEON bit (禁用 HSE 振荡器)*/
RCC->CR &= CR_HSEON_Reset;
/* Reset HSEBYP bit (外部1~25MHz振荡器未被旁路)*/
RCC->CR &= CR_HSEBYP_Reset;
/* 配置 HSE (RCC_HSE_OFF 已经被code核心代码覆盖了) */
switch(RCC_HSE)
{
case RCC_HSE_ON:
/* Set HSEON bit (打开 HSE 振荡器)*/
RCC->CR |= CR_HSEON_Set;
break;
case RCC_HSE_Bypass:
/* Set HSEBYP and HSEON bits (禁用 HSE 振荡器被外部1~25MHz振荡器和外部时钟旁路)*/
RCC->CR |= CR_HSEBYP_Set | CR_HSEON_Set;
break;
default:
break;
}
}
/**
* @简述 等待 HSE 启动.
* @参数 没有
* @返回 一个ErrorStatus枚举值:
* SUCCESS: HSE 振荡器已经稳定并且可以使用
* ERROR : HSE 振荡器尚未准备好
*/
ErrorStatus RCC_WaitForHSEStartUp(void)
{
__IO uint32_t StartUpCounter = 0;
ErrorStatus status = ERROR;
FlagStatus HSEStatus = RESET;
/* 等待 HSE 准备好和超时的时间到来 */
do
{
HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
StartUpCounter++;
} while((StartUpCounter != HSEStartUp_TimeOut) && (HSEStatus == RESET));
if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
{
status = SUCCESS;
}
else
{
status = ERROR;
}
return (status);
}
/**
* @简述 调整内部高速振荡器 (HSI) 标度值.
* @参数 HSICalibrationValue: 校正标度值,这个参数一定是在0到0x1F之间的值.
* @返回 没有
*/
void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
{
uint32_t tmpreg = 0;
/* 检查参数 */
assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue));
tmpreg = RCC->CR;
/* 清除 HSITRIM[4:0] 位 (默认值是16使 HIS 严格工作在8MHz) */
tmpreg &= CR_HSITRIM_Mask;
/* 设置 HSITRIM[4:0] 位,根据 HSICalibrationValue 的值 */
tmpreg |= (uint32_t)HSICalibrationValue << 3;
/* 存储新的值 */
RCC->CR = tmpreg;
}
/**
* @简述 使能或失能内部高速振荡器 (HSI).
* @注解 如果 HSE 被直接使用或者通过 PLL 作为系统时钟,则它不能停止.
* @参数 NewState: HSI 的新状态.
* 这个参数可取: ENABLE 或 DISABLE.
* @返回 没有
*/
void RCC_HSICmd(FunctionalState NewState)
{
/* 检查参数 */
assert_param(IS_FUNCTIONAL_STATE(NewState));
*(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState;
}
/**
* @简述 设置PLL时钟源及倍频系数.
* @注解 这个函数仅仅应用在 PLL 被禁止的时候.
* @参数 RCC_PLLSource: 指定进入 PLL 的时钟源.
* STM32_互联系列微处理器, 这个参数可取下列的值:
* RCC_PLLSource_HSI_Div2: PLL 时钟输入等于 HSI 振荡器时钟二分频
* RCC_PLLSource_PREDIV1: PREDIV1 clock selected as PLL clock entry
* 其它_STM32_微处理器, 这个参数可取下列的值:
* RCC_PLLSource_HSI_Div2: PLL 时钟输入等于 HSI 振荡器时钟二分频
* RCC_PLLSource_HSE_Div1: PLL 时钟输入等于 HSE 振荡器时钟
* RCC_PLLSource_HSE_Div2: PLL 时钟输入等于 HSE 振荡器时钟二分频
* @参数 RCC_PLLMul: 指定 PLL 倍频系数.
* STM32_Connectivity_line_devices, 这个参数可以是 RCC_PLLMul_x x可以取{[4,9], 6_5}
* other_STM32_devices, 这个参数可以是 RCC_PLLMul_x x可以取:[2,16]
* @返回 没有
*/
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
{
uint32_t tmpreg = 0;
/* 检查参数 */
assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
tmpreg = RCC->CFGR;
/* 清 PLLSRC, PLLXTPRE , PLLMUL[3:0] 位 */
tmpreg &= CFGR_PLL_Mask;
/* 设置 PLL 配置位 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -