TI中文支持网
TI专业的中文技术问题搜集分享网站

5438A 主频24M 不定时重启问题

5438A DCO用内部低频时钟源 倍频到24M,运行while(1) ; 会无规律(一个小时左右)重启一次,不知道是什么原因。希望有高手解答!非常感谢!

#define CLKSource_XT1 0
#define CLKSource_VLO 1
#define CLKSource_REFO 2
#define CLKSource_DCO 3
#define CLKSource_DCODLV 4
#define CLKSource_XT2 5
#define DEV_MCLK ((unsigned long)24000000)
#define DEV_SMCLK ((unsigned long)( 24000000))
#define DEV_ACLK ((unsigned long)( 32768))
#define FXT1 ((unsigned long)0)
#define FXT2 0
#define FDCO ((unsigned long )24000000)

void Delay_ms(unsigned long time);
void Delay_ms(unsigned long time);
void SetClock(unsigned long MCLK,unsigned char MCLKSource,unsigned long SMCLK,unsigned char SMCLKSource,unsigned long ACLK,unsigned char ACLKSource);

#define Delay_ms(x) __delay_cycles(DEV_MCLK/1000.0*x);
#define Delay_us(x) __delay_cycles(DEV_MCLK/1000000.0*x);

void SetVcoreUp (unsigned int level)
{
PMMCTL0_H = PMMPW_H;
SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level +SVSHFP+SVMHE+SVMHFP;
SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level +SVMLFP+SVMLE+SVSLFP;
while ((PMMIFG & SVSMLDLYIFG) == 0);
//PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
PMMIFG = 0;
PMMCTL0_L = PMMCOREV0 * level;
if ((PMMIFG & SVMLIFG))
while ((PMMIFG & SVMLVLRIFG) == 0);
SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
PMMIFG = 0;
PMMRIE|=SVMLVLRIE+SVMHVLRIE;
PMMCTL0_H = 0x00;
}

void SetClock(unsigned long MCLK,unsigned char MCLKSource,unsigned long SMCLK,unsigned char SMCLKSource,unsigned long ACLK,unsigned char ACLKSource)
{
P11SEL|=BIT0+BIT1+BIT2;
P11DIR|=BIT0+BIT1+BIT2;
double divf=0;
int divexp=0;
//晶振功能选择
if(FXT1>0)
{
P7SEL|=BIT0+BIT1; if(FXT1>=4000000)
{
UCSCTL6&=~XT1OFF;
UCSCTL6|=XCAP_3;
}
do
{
UCSCTL7 &= ~( XT1HFOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (UCSCTL7 & XT1HFOFFG); } if(FXT2>0)
{ UCSCTL6&=~XT2OFF;
P5SEL|=BIT2+BIT3; //do
{
UCSCTL7 &= ~(XT2OFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}//while (UCSCTL7 & XT2HFOFFG); } UCSCTL3=SELREF_3;
//时钟源选择
switch(ACLKSource)
{
case CLKSource_XT1:
if(FXT1>0)
{
UCSCTL4|=SELA_0;
//计算分频系数
if(FXT1>ACLK)
{
divf=frexp(FXT1/ACLK, &divexp);
UCSCTL5|=((divexp<<8)&(0x7<<8));
}
}
break;
case CLKSource_VLO:
UCSCTL4|=SELA_1;
break;
case CLKSource_REFO:
UCSCTL4|=SELA_2;
break;
case CLKSource_DCO:
{
UCSCTL4|=SELA_3;
}
break;
case CLKSource_DCODLV:
UCSCTL4|=SELA_4;
break;
case CLKSource_XT2:
if(FXT2>0)
{
UCSCTL4|=SELA_5;
if(FXT2>ACLK)
{
divf=frexp(FXT2/ACLK, &divexp);
if(divexp>0)
divexp–;
UCSCTL5|=((divexp<<8)&(0x7<<8));
}
}
break;
}
if(MCLK>=32768)
{
if(MCLK<12000000)
{
SetVcoreUp(1);
}
else if(MCLK<=20000000)
{
SetVcoreUp(1);
SetVcoreUp(2);
}
else if(MCLK<=25000000)
{
SetVcoreUp(1);
SetVcoreUp(2);
SetVcoreUp(3);
}
__delay_cycles(10000);
if (MCLK <= 630000) //fsystem < 0.63MHz
UCSCTL1 = DCORSEL_0;
else if (MCLK < 1250000) // 0.63MHz < fsystem < 1.25MHz
UCSCTL1 = DCORSEL_1;
else if (MCLK < 2500000) // 1.25MHz < fsystem < 2.5MHz
UCSCTL1 = DCORSEL_2;
else if (MCLK < 5000000) // 2.5MHz < fsystem < 5MHz
UCSCTL1 = DCORSEL_3;
else if (MCLK < 10000000) // 5MHz < fsystem < 10MHz
UCSCTL1 = DCORSEL_4;
else if (MCLK < 20000000) // 10MHz < fsystem < 20MHz
UCSCTL1 = DCORSEL_5;
else if (MCLK < 40000000) // 20MHz < fsystem < 40MHz
UCSCTL1 = DCORSEL_6;
else
UCSCTL1 = DCORSEL_7;
}

switch(SMCLKSource)
{
case CLKSource_XT1:
if(FXT1>0)
{
UCSCTL4|=SELS_0;
if(FXT1>SMCLK)
{
divf=frexp(FXT1/SMCLK, &divexp);
if(divexp>0)
divexp–;
UCSCTL5|=((divexp<<4)&(0x7<<4));
}
}
break;
case CLKSource_VLO:
UCSCTL4|=SELA_1;
break;
case CLKSource_REFO:
UCSCTL4|=SELS_2;
break;
case CLKSource_DCO:
UCSCTL4|=SELS_0;
if(FDCO>0)
{
UCSCTL4|=SELS_5;
if(FDCO>SMCLK)
{
divf=frexp(FDCO/SMCLK, &divexp);
if(divexp>0)
divexp–;
UCSCTL5|=((divexp<<4)&(0x7<<4));
}
}
UCSCTL4|=SELS_3;
break;
case CLKSource_DCODLV:
UCSCTL4|=SELS_4;
break;
case CLKSource_XT2:
if(FXT2>0)
{
UCSCTL4|=SELS_5;
if(FXT2>SMCLK)
{
divf=frexp(FXT2/SMCLK, &divexp);
if(divexp>0)
divexp–;
UCSCTL5|=((divexp<<4)&(0x7<<4));
}
}
break;
}
switch(MCLKSource)
{
case CLKSource_XT1:
if(FXT1>0)
{
UCSCTL4|=SELM_0;
if(FXT1>SMCLK)
{
divf=frexp(FXT1/MCLK, &divexp);
if(divexp>0)
divexp–;
UCSCTL5|=((divexp<<0)&(0x7<<0));
}
}
break;
case CLKSource_VLO:
UCSCTL4|=SELM_1;
break;
case CLKSource_REFO:
UCSCTL4|=SELM_2;
break;
case CLKSource_DCO:
UCSCTL2 = FLLD__1 + ((MCLK/32768)-1); //倍频 do
{
UCSCTL7 &= ~(DCOFFG); //等待DCO稳定
__delay_cycles(32*32);
}while (UCSCTL7 &DCOFFG); UCSCTL4|=SELM_3; //主频切换

break;
case CLKSource_DCODLV:
UCSCTL4|=SELM_4;
break;
case CLKSource_XT2:
if(FXT2>0)
{
UCSCTL4|=SELM_5;
if(FXT2>MCLK)
{
divf=frexp(FXT2/SMCLK, &divexp);
if(divexp>0)
divexp–;
UCSCTL5|=((divexp<<0)&(0x7<<0));
}
}
break;
} __delay_cycles((unsigned long )32*32*1000);}

int main()
{
WDTCTL = WDTPW + WDTHOLD;

APPSendPulse_Start();//GPIO 操作继电器
while(1);

}

灰小子:

因为是无规律的重启,所以不太好判断具体是什么原因导致的。只能用排除发一部分一部分的排除。

看到你的主程序里有继电器相关操作,建议断开该部分电路进行测试。

还有就是检查供电和复位电路是否收到干扰和毛刺等

FQ Zhao:

回复 灰小子:

继电器只在程序运行开始运行一次,而且电源完全独立,中间用光耦隔离开;复位引脚也检查过,也用过UNMI检查(开UNMI中断,点灯),SNMI也检查过(开启SVS的电压高重启中断和电压低重启中断)没有遇到灯亮的情况;供电部分用示波器触发,有时能抓到50-100ns的小毛刺,但是似乎和重启并不是一一对应的,有时重启的时候确实抓到过毛刺(因为不可能一直盯着示波器,而重启后继电器会响,有时候听到响声后看示波器抓到毛刺),但有的时候示波器抓到毛刺而又没有重启。 我想下一步准备关闭SVS观察一下,不知道还有没有好的方法。

HG:

调用Vcoreup一步一步升到最高电压,此外检查VCORE引脚的电容是否与Datasheet建议值吻合。

FQ Zhao:

回复 HG:

代码上确实是逐步提高的内核电压if(MCLK>=32768){if(MCLK<12000000){SetVcoreUp(1);}else if(MCLK<=20000000){SetVcoreUp(1);SetVcoreUp(2);}else if(MCLK<=25000000){SetVcoreUp(1);SetVcoreUp(2);SetVcoreUp(3);}

内核电压引脚处电容为100nf 推荐值是470nf,请问100nf是不是不可以的?

FQ Zhao:

回复 HG:

电容换成470nf还是会重启!

赞(0)
未经允许不得转载:TI中文支持网 » 5438A 主频24M 不定时重启问题
分享到: 更多 (0)