关于MSP430F449时钟
前几周使用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;
}
/******************************************************/
这段代码已经经过反复测试,再也没有遇到时钟初始化通不过的情况了。
MSP430F449时 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)