📄 rccu.c
字号:
// rccu.c
#include "rccu.h"
/*******************************************************************************
* 说明:RCCU_PLL1Config函数,配置PLL1乘、除因子
* 参数:New_Mul为乘法因子( RCCU_PLL1_Mul_12, RCCU_PLL1_Mul_16, RCCU_PLL1_Mul_20,
* RCCU_PLL1_Mul_24 )
* New_Div为除法因子 ( RCCU_Div_1, RCCU_Div_2, RCCU_Div_3, RCCU_Div_4,
* RCCU_Div_5, RCCU_Div_6, RCCU_Div_7)
* 返回值:无
*******************************************************************************/
void RCCU_PLL1Config ( RCCU_PLL1_Mul New_Mul, RCCU_PLL_Div New_Div ) {
u32 Tmp = ( RCCU->PLL1CR & ~RCCU_MX_Mask ) | ( New_Mul << RCCU_MX_Index );
RCCU->PLL1CR = ( Tmp & ~RCCU_DX_Mask ) | New_Div | 0x40;
}
/*******************************************************************************
* 说明:RCCU_PLL2Config函数,配置PLL2乘、除因子
* 参数:New_Mul为乘法因子( RCCU_PLL1_Mul_12, RCCU_PLL1_Mul_16, RCCU_PLL1_Mul_20,
* RCCU_PLL1_Mul_24 )
* New_Div为除法因子 ( RCCU_Div_1, RCCU_Div_2, RCCU_Div_3, RCCU_Div_4,
* RCCU_Div_5, RCCU_Div_6, RCCU_Div_7)
* 返回值:无
*******************************************************************************/
void RCCU_PLL2Config ( RCCU_PLL2_Mul New_Mul, RCCU_PLL_Div New_Div ) {
u32 Tmp = ( PCU->PLL2CR & ~RCCU_MX_Mask ) | ( New_Mul << RCCU_MX_Index );
PCU->PLL2CR = ( Tmp & ~RCCU_DX_Mask ) | ( New_Div | RCCU_FREEN_Mask );
}
/*******************************************************************************
* 说明:RCCU_RCLKSourceConfig函数,选择RCLK源时钟
* 参数:New_Clock为新选时钟 ( RCCU_PLL1_Output, RCCU_CLOCK2_16, RCCU_CLOCK2 )
* 返回值:无
*******************************************************************************/
void RCCU_RCLKSourceConfig ( RCCU_RCLK_Clocks New_Clock ) {
switch ( New_Clock ) {
case RCCU_CLOCK2 :{// 复位 CSU_Cksel 位
RCCU->CFR &= ~RCCU_CSU_CKSEL_Mask;
// 置位 CK2_16 位
RCCU->CFR |= RCCU_CK2_16_Mask;
// 反选 CKAF
RCCU->CCR &= ~RCCU_CKAF_SEL_Mask;
// 关闭 PLL1
RCCU->PLL1CR=((RCCU->PLL1CR & ~RCCU_DX_Mask)\
|0x00000003) & ~RCCU_FREEN_Mask;
break;}
case RCCU_CLOCK2_16 :{// 复位 CK2_16 位
RCCU->CFR &= ~RCCU_CK2_16_Mask;
// 反选 CKAF
RCCU->CCR &= ~RCCU_CKAF_SEL_Mask;
// 关闭 PLL1
RCCU->PLL1CR=((RCCU->PLL1CR & ~RCCU_DX_Mask)\
|0x00000003) & ~RCCU_FREEN_Mask;
break;}
case RCCU_PLL1_Output:{// 置位 CK2_16 位
RCCU->CFR = RCCU->CFR | RCCU_CK2_16_Mask;
// 等待 PLL1 锁定
if (( RCCU->PLL1CR & 0x0007 ) != 7)
while(!(RCCU->CFR & RCCU_LOCK_Mask));
// 反选 CKAF
RCCU->CCR &= ~RCCU_CKAF_SEL_Mask;
// 选中 CSU_CKSEL
RCCU->CFR |= RCCU_CSU_CKSEL_Mask;
break;}
case RCCU_RTC_CLOCK : {RCCU->CCR |= 0x04;
break;}
}
}
/*******************************************************************************
* 说明:RCCU_RCLKClockSource函数,返回当前 RCLK 源时钟
* 参数:无
* 返回值: RCCU_PLL1_Output, RCCU_CLOCK2_16, RCCU_CLOCK2, RCCU_RTC_CLOCK
*******************************************************************************/
RCCU_RCLK_Clocks RCCU_RCLKClockSource ( void ) {
if ((RCCU->CCR & 0x04)==0x04)
return RCCU_RTC_CLOCK;
else if ((RCCU->CFR & RCCU_CK2_16_Mask)==0)
return RCCU_CLOCK2_16;
else if (RCCU->CFR & RCCU_CSU_CKSEL_Mask)
return RCCU_PLL1_Output;
else
return RCCU_CLOCK2;
}
/*******************************************************************************
* 说明: RCCU_USBClockSource函数,获得 RCLK 源时钟
* 参数:无
* 返回值:RCCU_USB_Clocks ( RCCU_PLL2_Output, RCCU_USBCK )
*******************************************************************************/
RCCU_USB_Clocks RCCU_USBClockSource ( void ) {
if ((PCU->PLL2CR & RCCU_USBEN_Mask ) >> RCCU_USBEN_Index == 1 )
return RCCU_PLL2_Output;
else return RCCU_USBCK;
}
/*******************************************************************************
* 说明:RCCU_FrequencyValue函数,校准并返回由参数传递的任意内部 RCCU 时钟频率
* 参数:RCCU_Clocks ( RCCU_CLK2, RCCU_RCLK, RCCU_MCLK, RCCU_PCLK, RCCU_FCLK )
* 返回值:u32
*******************************************************************************/
u32 RCCU_FrequencyValue ( RCCU_Clocks Internal_Clk ) {
u32 Tmp;
u8 Div = 0;
u8 Mul = 0;
RCCU_RCLK_Clocks CurrentRCLK;
Tmp = ( RCCU_Div2Status() == SET )? RCCU_Main_Osc / 2 : RCCU_Main_Osc;
if ( Internal_Clk == RCCU_CLK2 ) {
Div = 1;
Mul = 1;
}
else {
CurrentRCLK = RCCU_RCLKClockSource ();
switch ( CurrentRCLK ){
case RCCU_CLOCK2_16 : Div = 16;
Mul = 1;
break;
case RCCU_CLOCK2 : Div = 1;
Mul = 1;
break;
case RCCU_PLL1_Output :{
Mul=(RCCU->PLL1CR & RCCU_MX_Mask ) >> RCCU_MX_Index;
switch ( Mul ) {
case 0: Mul = 20; break;
case 1: Mul = 12; break;
case 2: Mul = 24; break;
case 3: Mul = 16; break;
}
Div = ( RCCU->PLL1CR & RCCU_DX_Mask ) + 1;
break;
}
case RCCU_RTC_CLOCK : Mul = 1;
Div = 1;
Tmp = RCCU_RTC_Osc;
break;
}
}
switch ( Internal_Clk ){
case RCCU_MCLK :{Div <<= PCU->MDIVR & RCCU_FACT_Mask;
break;
}
case RCCU_PCLK :{
Div <<=(PCU->PDIVR & RCCU_FACT2_Mask ) >> RCCU_FACT2_Index;
break;
}
case RCCU_FCLK :{
Div <<= PCU->PDIVR & 0x3;
break;
}
}
return (Tmp * Mul) / Div;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -