TI专家您好:
我使用的单片机型号是msp430fr2111,使用DCO作为MCLK,上电到时钟稳定要用80ms左右,我个人觉得这个时间太长了,我时钟初始化参考的都是官网下载的相关例程,请问这种条件下时钟稳定要80ms正常吗?
时钟初始化我参考的里程文件时msp430fr211x_CS_01.c
下面是时钟初始化相关函数
void clkInit(void)
{
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM=3, DCO Range = 8MHz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
Software_Trim(); // Software Trim to get the best DCOFTRIM value
CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
}
void Software_Trim()
{
unsigned int oldDcoTap = 0xffff;
unsigned int newDcoTap = 0xffff;
unsigned int newDcoDelta = 0xffff;
unsigned int bestDcoDelta = 0xffff;
unsigned int csCtl0Copy = 0;
unsigned int csCtl1Copy = 0;
unsigned int csCtl0Read = 0;
unsigned int csCtl1Read = 0;
unsigned int dcoFreqTrim = 3;
unsigned char endLoop = 0;
do
{
CSCTL0 = 0x100; // DCO Tap = 256
do
{
CSCTL7 &= ~DCOFFG; // Clear DCO fault flag
}while (CSCTL7 & DCOFFG); // Test DCO fault flag
__delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ);// Wait FLL lock status (FLLUNLOCK) to be stable
// Suggest to wait 24 cycles of divided FLL reference clock
while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));
csCtl0Read = CSCTL0; // Read CSCTL0
csCtl1Read = CSCTL1; // Read CSCTL1
oldDcoTap = newDcoTap; // Record DCOTAP value of last time
newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value
if(newDcoTap < 256) // DCOTAP < 256
{
newDcoDelta = 256 – newDcoTap; // Delta value between DCPTAP and 256
if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
endLoop = 1; // Stop while loop
else
{
dcoFreqTrim–;
CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
}
}
else // DCOTAP >= 256
{
newDcoDelta = newDcoTap – 256; // Delta value between DCPTAP and 256
if(oldDcoTap < 256) // DCOTAP cross 256
endLoop = 1; // Stop while loop
else
{
dcoFreqTrim++;
CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
}
}
if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
{
csCtl0Copy = csCtl0Read;
csCtl1Copy = csCtl1Read;
bestDcoDelta = newDcoDelta;
}
}while(endLoop == 0); // Poll until endLoop == 1
CSCTL0 = csCtl0Copy; // Reload locked DCOTAP
CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
}
灰小子:
一般带bootloader的单片机在进入main之前会先执行bootloader的代码,里面会有检测io时序、延时等代码,会比较占用时间。
Susan Yang:
更多详细信息您可以看一下数据手册的 5.13 Timing and Switching Characteristics
www.ti.com.cn/…/msp430fr2111.pdf
Hao Mengzhen:
你的代码跑了software trim,这段代码持续的时间是未知的。这个software trim主要是将DCO锁在一个稳定准确的频率上,需要找到具体的微调数值将频率锁在精确的8MHz。如果你的程序跑过一遍software trim后,你可以把微调数值写进FRAM里,下次上电时直接用之前存进去的微调数值,这样就可以不用跑software trim这段代码将会省很多时间。
Ling Zhu2:
还有一个办法,DCO 设到16MHz,就不用跑 software trim 了。可以省不少时间。
HG:
回复 Ling Zhu2:
Software_Trim其实就是为了算 csCtrol0和csCtrol1的值,代码看着慢,但要是量产的时候在产线上算好了,在现场就可以直接load了,就很快了。可以不用,就是会有精度损失,
1.如果用LFXT,提前算好是靠谱的办法,这样只能产线上加一道工序,先算好存在FRAM的某个地址,代码里直接调用。
2.用片外高频晶振做,容易多了。