使用的时钟切换方式为手动切换,在中断中进行时钟切换,然后将切换后的主时钟输出到CLK_CCO口
时钟切换流程图(手动切换流程图):
时钟树:
寄存器版:
unsigned char i=255;
PD_DDR_DDR0=1;//配置PD0为输出模式
PD_CR1_C10=1;//配置PD0为推挽模式
PD_CR2_C20=1;//配置PD0输出最大为10Mhz
if(CLK_CMSR==0xE1) //如果HSI为主时钟源(复位值),切换到HSE
{
CLK_SWCR_SWIEN=1;//时钟切换中断使能
CLK_SWR=0xB4;//HSE为主时钟源
asm("rim");//开启全局中断
}
while(CLK_SWCR_SWBSY)//等待忙标志复位
{
i--;
if(i==0) {
CLK_SWCR_SWBSY=0;//如果时钟切换没有成功,清除标志位SWBSY以复位当前的切换操作
break;
}
}
while(CLK_CCOR_CC0BSY);//等待CCO时钟空闲 (0:CCO时钟空闲)
CLK_CCOR_CCOSEL=0x0c;//配置时钟输出源选择Fhse
CLK_CCOR_CCOEN=1;//使能CCO时钟输出
while(1);
}
#pragma vector=CLK_SWITCH_vector
__interrupt void CLK_IRQHandler(void)
{
CLK_SWCR_SWIF=0;//清除中断标志
CLK_SWCR_SWEN=1;//使能时钟切换的执行
}
库函数版:
main.c文件
void main(void)
{
CLK_DeInit();//重置时钟相关寄存器到默认复位值
GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);//高速(10MHz)推挽高电平输出
enableInterrupts();//使能全局中断
ErrorStatus es;
es = CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSE, ENABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
//手动切换;新的时钟源:HSE;启动切换中断;保持原时钟源开启
if (es == SUCCESS) //切换是否成功,SUCCESS or ERROR
{
CLK_CCOConfig(CLK_OUTPUT_MASTER);//配置时钟输出脚的时钟源:f(master)
CLK_CCOCmd(ENABLE);//启动时钟输出功能
};
/* Infinite loop */
while (1)
{
}
}
stm8s_it.c文件
INTERRUPT_HANDLER(CLK_IRQHandler, 2)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
ITStatus flags_tatus;
flags_tatus = CLK_GetITStatus(CLK_IT_SWIF);//检测时钟切换中断标志
if (flags_tatus == SET) //如果时钟切换中断标志SWIF是置位状态,SET or RESET
{
CLK_ClearITPendingBit(CLK_IT_SWIF);//清除时钟切换中断标志
CLK_ClockSwitchCmd(ENABLE);//启动时钟切换功能
};
}
结果: