仅分析了一下内部22.1148MHZ时钟与外部12MHZ晶振时钟的切换。
若用户配置字CONFIG配置为:复位后cpu时钟源选择为内部22.1148MHZ时钟。在系统上电复位后,PWRCON 的OSC22M_EN自动置位,XTL12M_EN默认为0。系统将采用内部22.1148MHZ时钟执行指令,直到用户程序切换时钟,此时即使将oscin与oscout短路也不影响系统运行。下面进行时钟切换,并逐步完善。
1、PWRCON|=XTL12M_EN;//使能外部12MHZ晶振。 即使板子上没有安装外部晶振或外部晶振损坏,一样可以使能外部晶振
CLKSEL0=(CLKSEL0&(~HCLK))|HCLK_12M;//系统时钟选择为外部12M时钟
上面的写法是错误的,执行PWRCON|=XTL12M_EN后,外部12M时钟并没有稳定,然后切换时钟是会失败的。切换系统时钟失败后,系统仍会采用原先的内部22.1148MHZ时钟执行指令,这样会产生很多问题。
2、PWRCON|=XTL12_EN;
while((CLKSTATUS&XTL12M_STB)==0);//等待外部12M时钟稳定
CLKSEL0=(CLKSEL0&(~HCLK)|HCLK_12M;
上面的写法可以实现时钟的切换,等待外部12M时钟稳定以后,切换时钟,一般情况下是可以切换成功的。但如果在程序执行CLKSEL0=(CLKSEL0&(~HCLK)|HCLK_12M的指令时,如果外部晶振突然失效(虽然记录很小),仍然会切换时钟失败。
3、 do
{
CLKSTATUS|=CLK_SW_FAIL;//清零时钟切换失败标志位
PWRCON|=XTL12M_EN;//使能外部12M时钟
while((CLKSTATUS&XTL12M_STB)==0);//等待12M时钟稳定
CLKSEL0=(CLKSEL0&(~HCLK))|HCLK_12M;//将12M时钟作为系统时钟
}
while(CLKSTATUS&(CLK_SW_FAIL)); //若时钟切换失败,则继续切换
上面的写法,保证了无论在什么情况下切换时钟失败,都会循环下去,一直进行时钟切换。:lol
在时钟切换完成后,若果外部12M时钟失效,单片机会停止运行,时钟恢复后会继续停止处运行。
|