SP430系列MCU的卖点是超低功耗,除了端口的低漏电流之最之外,我以为和低功耗联系最大的莫过于他的时钟模块了。典型的430CPU一般能够在3个震动器之中选取时钟源:低频晶体(LFXT)、高频晶体(XT)和内部的数控RC振荡器(DCO)。
前几周运用MSP430F449做产品,由于之前成功地运用过MSP430F149做过东西,心想449也是一个模子出来的换汤不换药,遂心中有数,殊不知,几乎栽了跟头,就在这个多时钟源的时钟模块上。
449和149的时钟模块的最大差异在于449的时钟包含了可编程FLL模块,翻开449的头文件,连寄存器的姓名都和149彻底不一样,全部均以“FLL”最初。少顷,但见其内容迥然不同,遂把曾经的写的149的时钟初始化代码中的寄存器改了名号,直接用在了449上。可是立刻就呈现了问题:在测验IFG1中的时钟失效标志位OFIFG之时,会不定期地呈现OFIFG一向不复位的状况,程序就这样在这里止步不前(OFIFG置位表明至少有一个时钟源实效,假如置之脑后,强行运转下面的代码的话,CPU有或许会强制运用DCO作为MCLK时钟源,这样就会使守时操作呈现过错)。我的板子上接了32K的LFXT和8M的XT2,遂置疑匹配负载电容有问题,由于低速晶体振荡器LFXT供给了内置的匹配电容。可是不论怎样调配内部与外部电容,一向不得解。
这之后的某日,我借出恭之便细心研读了449文档里的时钟模块相关内容,发现OFIFG竟然是时钟模块操控寄存器FLL_CTL0中XT1OF、XT2OF、LFOF、DCOF这4的状况位相或的成果,登时灵光一现,遂编写代码将相关状况坐落几个管脚上LED相关,观察其状况,成果令我大吃一惊:我一向以为有严重嫌疑的LFXT和XT并没有任何问题,LFOF与XT2OF都会在上电后瞬间复位,而我一向觉得肯定不会有问题的DCOF却一向置位!
接下来,我细心查阅了文档,本来在SCFI1中有5位设置了DCO tap数值,这个数值若这个数值设置的过高或过低都会使DCOF置位,从而使OFIFG置位,而PUC后这五位都是复位的,就是说,DCO tap值在PUC后被设置为最低值0,所以有或许会使DCOF置位。
上网搜了一下,其实这个DCO仍是蛮强壮的,虽然其频率会遭到温度与电压的影响,通过调整也能抵达适当的精度。由于我现已把LFXT和XT都备全了,这个使用也不需要节电,所以没有再太多的研讨这个DCO究竟怎样用,在程序里做了个计数,把DCO tap一切的或许数值都试了一下,以确保时钟初始化的顺畅。
我最终时钟初始化代码如下,以供和我遇到相同问题的朋友参阅。
/******************************************************/
//初始化体系时钟
void SysClkInit(void)
{
unsigned int i;
unsigned char DCOtap = 0x01;
SCFQCTL |= SCFQ_M;
FLL_CTL0 &= XCAP18PF;
_BIS_SR(OSCOFF);
FLL_CTL1 &= ~XT2OFF;
IFG1 &= ~OFIFG; // Clear oscillator fault flag
do
{
IFG1 &= ~OFIFG;
for (i = 5000; i; i–); // Delay
SCFI1 |= ((DCOtap++) & 0x0f) << 3;
} while (IFG1 & OFIFG); // Test osc fault flag
FLL_CTL1 = (SELM1 + SELS); // Select SMCLK source as XT2CLK
return;
}
/******************************************************/
这段代码现现已过重复测验,再也没有遇到时钟初始化通不过的状况了。