📄 stm32f10x_rcc.c
字号:
assert_param(IS_RCC_OTGFSCLK_SOURCE(RCC_OTGFSCLKSource));
*(__IO uint32_t *) CFGR_OTGFSPRE_BB = RCC_OTGFSCLKSource;
}
#endif /* STM32F10X_CL */
/**
* @简述 配置 ADC 时钟 (ADCCLK).
* @参数 RCC_PCLK2: 定义 ADC 时钟分频. 这个时钟来源于 APB2 时钟 (PCLK2).
* 这个参数可以取下列值中的一个:
* RCC_PCLK2_Div2: ADC clock = PCLK2/2
* RCC_PCLK2_Div4: ADC clock = PCLK2/4
* RCC_PCLK2_Div6: ADC clock = PCLK2/6
* RCC_PCLK2_Div8: ADC clock = PCLK2/8
* @返回 没有
*/
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
{
uint32_t tmpreg = 0;
/* 检查参数 */
assert_param(IS_RCC_ADCCLK(RCC_PCLK2));
tmpreg = RCC->CFGR;
/* 清 ADCPRE[1:0] 位 */
tmpreg &= CFGR_ADCPRE_Reset_Mask;
/* 设置 ADCPRE[1:0] 位取决于 RCC_PCLK2 的值 */
tmpreg |= RCC_PCLK2;
/* 存储新值 */
RCC->CFGR = tmpreg;
}
#ifdef STM32F10X_CL
/**
* @简述 配置 I2S2 时钟源(I2S2CLK).
* @注解
* - 这个函数必须在使能I2S2 APB时钟之前调用.
* - 这个函数仅仅应用在 STM32 互联系列微处理器.
* @参数 RCC_I2S2CLKSource: 指定 I2S2 时钟源.
* 这个参数可以取下列值中的一个:
* RCC_I2S2CLKSource_SYSCLK: 系统时钟作为 I2S2 时钟源
* RCC_I2S2CLKSource_PLL3_VCO: PLL3 VCO 作为 I2S2 时钟源
* @返回 没有
*/
void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource)
{
/* 检查参数 */
assert_param(IS_RCC_I2S2CLK_SOURCE(RCC_I2S2CLKSource));
*(__IO uint32_t *) CFGR2_I2S2SRC_BB = RCC_I2S2CLKSource;
}
/**
* @简述 配置 I2S3 时钟源(I2S2CLK).
* @注解
* - 这个函数必须在使能I2S3 APB时钟之前调用.
* - 这个函数仅仅应用在 STM32 互联系列微处理器.
* @参数 RCC_I2S3CLKSource: 指定 I2S3 时钟源.
* 这个参数可以取下列值中的一个:
* RCC_I2S2CLKSource_SYSCLK: 系统时钟作为 I2S3 时钟源
* RCC_I2S2CLKSource_PLL3_VCO: PLL3 VCO 作为 I2S3 时钟源
* @返回 没有
*/
void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource)
{
/* 指定参数 */
assert_param(IS_RCC_I2S3CLK_SOURCE(RCC_I2S3CLKSource));
*(__IO uint32_t *) CFGR2_I2S3SRC_BB = RCC_I2S3CLKSource;
}
#endif /* STM32F10X_CL */
/**
* @简述 配置外部低速振荡器 (LSE).
* @参数 RCC_LSE: 指定 LSE 的新状态.
* 这个参数可以取下列值中的一个:
* RCC_LSE_OFF: LSE 振荡器 OFF
* RCC_LSE_ON: LSE 振荡器 ON
* RCC_LSE_Bypass: LSE 振荡器与外部时钟旁路
* @返回 没有
*/
void RCC_LSEConfig(uint8_t RCC_LSE)
{
/* 检查参数 */
assert_param(IS_RCC_LSE(RCC_LSE));
/* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/
/* 复位 LSEON 位 */
*(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF;
/* 复位 LSEBYP 位 */
*(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF;
/* Configure LSE (RCC_LSE_OFF 已经在 code 代码部分被覆盖) */
switch(RCC_LSE)
{
case RCC_LSE_ON:
/* 设置 LSEON 位 */
*(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON;
break;
case RCC_LSE_Bypass:
/* 设置 LSEBYP , LSEON 位 */
*(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON;
break;
default:
break;
}
}
/**
* @简述 使能或失能内部低速振荡器 (LSI).
* @注解 如果 IWDG 正在运行,LSI 就不能被禁用.
* @参数 NewState: LSI 新的状态. 这个参数可以取: ENABLE 或 DISABLE.
* @返回 没有
*/
void RCC_LSICmd(FunctionalState NewState)
{
/* 检查参数 */
assert_param(IS_FUNCTIONAL_STATE(NewState));
*(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState;
}
/**
* @简述 配置 RTC 时钟 (RTCCLK).
* @注解 只要选择了 RTC 时钟,RTC时钟就不能改变直到备份域复位.
* @参数 RCC_RTCCLKSource: 指定 RTC 时钟源.
* 这个参数可以取下列值中的一个:
* RCC_RTCCLKSource_LSE: LSE 作为 RTC 时钟
* RCC_RTCCLKSource_LSI: LSI 作为 RTC 时钟
* RCC_RTCCLKSource_HSE_Div128: HSE 时钟的 128 分频作为 RTC 时钟
* @返回 没有
*/
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)
{
/* 检查参数 */
assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource));
/* 指定 RTC 时钟源 */
RCC->BDCR |= RCC_RTCCLKSource;
}
/**
* @简述 使能或失能 RTC 时钟.
* @注解 仅当使用 RCC_RTCCLKConfig 函数选择 RTC 时钟后,才使用这个函数.
* @参数 NewState: RTC 时钟的新状态. 这个参数可以取: ENABLE 或 DISABLE.
* @返回 没有
*/
void RCC_RTCCLKCmd(FunctionalState NewState)
{
/* 检查参数 */
assert_param(IS_FUNCTIONAL_STATE(NewState));
*(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState;
}
/**
* @简述 返回片上时钟的不同频率.
* @参数 RCC_Clocks: 指向包括时钟频率的 RCC_ClocksTypeDef 结构的指针.
* @返回 没有
*/
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;
#ifdef STM32F10X_CL
uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */
/* 得到系统时钟源 -------------------------------------------------------*/
tmp = RCC->CFGR & CFGR_SWS_Mask;
switch (tmp)
{
case 0x00: /* HSI used as system clock */
RCC_Clocks->SYSCLK_Frequency = HSI_Value;
break;
case 0x04: /* HSE used as system clock */
RCC_Clocks->SYSCLK_Frequency = HSE_Value;
break;
case 0x08: /* PLL used as system clock */
/* 得到 PLL 时钟源和倍频因数 ----------------------*/
pllmull = RCC->CFGR & CFGR_PLLMull_Mask;
pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;
#ifndef STM32F10X_CL
pllmull = ( pllmull >> 18) + 2;
if (pllsource == 0x00)
{/* HSI 振荡时钟的2分频作为 PLL 时钟源 */
RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull;
}
else
{/* HSE 作为 PLL 时钟源 */
if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
{/* HSE 振荡时钟被2分频 */
RCC_Clocks->SYSCLK_Frequency = (HSE_Value >> 1) * pllmull;
}
else
{
RCC_Clocks->SYSCLK_Frequency = HSE_Value * pllmull;
}
}
#else
pllmull = pllmull >> 18;
if (pllmull != 0x0D)
{
pllmull += 2;
}
else
{ /* PLL 倍频因数 = PLL 输入时钟 * 6.5 */
pllmull = 13 / 2;
}
if (pllsource == 0x00)
{/* HSI 振荡时钟被2分频作为 PLL 时钟源 */
RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull;
}
else
{/* PREDIV1 作为 PLL 时钟源 */
/* 指定 PREDIV1 时钟源和分频系数 */
prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;
prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
if (prediv1source == 0)
{ /* HSE 振荡时钟被选定作为 PREDIV1 时钟源 */
RCC_Clocks->SYSCLK_Frequency = (HSE_Value / prediv1factor) * pllmull;
}
else
{/* PLL2 时钟作为 PREDIV1 时钟源 */
/* 指定 PREDIV2 分频系数 和 PLL2 倍频系数 */
prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;
pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2;
RCC_Clocks->SYSCLK_Frequency = (((HSE_Value / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
}
}
#endif /* STM32F10X_CL */
break;
default:
RCC_Clocks->SYSCLK_Frequency = HSI_Value;
break;
}
/* 计算 HCLK, PCLK1, PCLK2 , ADCCLK 时钟频率 ----------------*/
/* 得到 HCLK 预分频器 */
tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
tmp = tmp >> 4;
presc = APBAHBPrescTable[tmp];
/* HCLK 时钟频率 */
RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
/* 得到 PCLK1 预分频器 */
tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
tmp = tmp >> 8;
presc = APBAHBPrescTable[tmp];
/* PCLK1 时钟频率 */
RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
/* 得到 PCLK2 预分频器 */
tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
tmp = tmp >> 11;
presc = APBAHBPrescTable[tmp];
/* PCLK2 时钟频率 */
RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
/* 得到 ADCCLK 预分频器 */
tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;
tmp = tmp >> 14;
presc = ADCPrescTable[tmp];
/* ADCCLK 时钟频率 */
RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}
/**
* @简述 使能或失能 AHB 外围设备时钟.
* @参数 RCC_AHBPeriph: 用于门控时钟的 AHB 外围设备.
*
* STM32_互联系列微处理器, 这个参数可以取下列值中的一个:
* RCC_AHBPeriph_DMA1
* RCC_AHBPeriph_DMA2
* RCC_AHBPeriph_SRAM
* RCC_AHBPeriph_FLITF
* RCC_AHBPeriph_CRC
* RCC_AHBPeriph_OTG_FS
* RCC_AHBPeriph_ETH_MAC
* RCC_AHBPeriph_ETH_MAC_Tx
* RCC_AHBPeriph_ETH_MAC_Rx
*
* 其它_STM32_微处理器, 这个参数可以取下列值中的一个:
* RCC_AHBPeriph_DMA1
* RCC_AHBPeriph_DMA2
* RCC_AHBPeriph_SRAM
* RCC_AHBPeriph_FLITF
* RCC_AHBPeriph_CRC
* RCC_AHBPeriph_FSMC
* RCC_AHBPeriph_SDIO
*
* @注解 SRAM 和 FLITF 时钟只有在睡眠的模式下可以无效.
* @参数 NewState: 指定外围设备时钟新的状态.
* 这个参数可以取: ENABLE 或 DISABLE.
* @返回 没有
*/
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
{
/* 检查参数 */
assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
RCC->AHBENR |= RCC_AHBPeriph;
}
else
{
RCC->AHBENR &= ~RCC_AHBPeriph;
}
}
/**
* @简述 使能或失能高速 APB (APB2) 外围设备时钟.
* @参数 RCC_APB2Periph: 用于门控时钟的 AHB2 外围设备.
* 这个参数可以是下面任意值的组合:
* 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
* @参数 NewState: 指定外围设备时钟的新状态.
* 这个参数可以取: ENABLE 或 DISABLE.
* @返回 没有
*/
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
/* 检查参数 */
assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
RCC->APB2ENR |= RCC_APB2Periph;
}
else
{
RCC->APB2ENR &= ~RCC_APB2Periph;
}
}
/**
* @简述 使能或失能低速 APB (APB1) 外围设备时钟.
* @参数 RCC_APB1Periph: 用于门控时钟的 APB1 外围设备.
* 这个参数可以是下面任意值的组合:
* RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4,
* RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -