如题,使用内部DCO-8M。MCU进入低功耗LPM3模式后,定时唤醒MCU通过引脚输出MCLK波形,发现每次唤醒后MCLK频率会逐步升高,多次唤醒后导致单片机自动死机。
随后,试了LPM0、LPM1、LPM2这几种模式,多次唤醒后MCLK比较稳定不会升高。
为了节省系统休眠功耗,而提高唤醒处理速度,不知道LPM3模式唤醒后,如何处理DCO不稳定的情况。
Lina Lian:
peng peng,
MCLK从DCO来,而DCO是由FLL提供的,FLL每次启动或变化设置,都是需要一定时间来达到稳定的。
1. 请问你是否使用了TI提供的core library,来对UCS和PMM进行配置?如果使用了,请使用最新版本的core library?
2. 请问在LPM3下唤醒后MCLK频率会逐步升高,是多长时间内会升到多高?请详细描述一下现象。
3. 多次唤醒后导致单片机自动死机,请问你是如何判断自动死机的?硬件复位可否恢复?
pengpeng:
回复 Lina Lian:
1.目前使用的就是TI提供的core library代码来修改的,以下程序是在MSP430F530x_UCS_02基础上修改的,每秒看门狗定时唤醒一次,并通过P4.7输出MCLK。
2.通过调节while(1)主循环中__delay_cycles()延时函数可以出现不同的现象:
当延时系数为10时,多次唤醒后频率比较稳定,都在8Mhz左右,没出现逐步升高迹象。(无死机现象)
当延时系数为100时,多次唤醒后频率逐步升高,开始运行时8Mhz左右,两分钟过后达到15.62Mhz。(无死机现象)
当延时系数为200时,多次唤醒后频率逐步升高,开始运行时8Mhz左右,两分钟过后达到18.72Mhz。(无死机现象)
当延时系数为220时,多次唤醒后频率逐步升高,开始运行时8Mhz左右,两分钟过后达到18.72Mhz。(有死机现象,三分钟左右就会死机)
3.当系数为220时,三分钟左右就会死机,死机后,P4.2-IO_Text_H1被执行,一直处于高电平,P4.7-MCLK引脚一直输出8Mhz频率波形。可以通过硬件/RST引脚复位恢复。
代码如下:
#include <msp430f5310.h>//标准库#define IO_Text_H1 P4OUT |= BIT2#define IO_Text_L1 P4OUT &=~BIT2
int main(void){WDTCTL = WDTPW|WDTHOLD; // Stop WDT//1)通用IO口配置-统计为输出低电平P1DIR = 0xFF; P1OUT = 0x00;P2DIR = 0xFF; P2OUT = 0x00;P3DIR = 0xFF; P3OUT = 0x00;P4DIR = 0xFF; P4OUT = 0x00;P5DIR = 0xFF; P5OUT = 0x00;P6DIR = 0xFF; P6OUT = 0x00;PJDIR = 0xFF; PJOUT = 0x00;//JTAG引脚配置P4SEL |= BIT7;P4DIR |= BIT7; //P4.7 MCLK set out to pinsPMAPPWD = 0x02D52; //使能端口映射寄存器写入访问P4MAP7 = PM_MCLK;PMAPPWD = 0; // 禁止端口映射寄存器写入访问 //2)系统时钟初始化-UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFOUCSCTL4 |= SELA_2; // Set ACLK = REFOUCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx// Loop until XT1,XT2 & DCO stabilizes – In this case only DCO has to stabilizedo{UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);// Clear XT2,XT1,DCO fault flagsSFRIFG1 &= ~OFIFG; // Clear fault flags}while (SFRIFG1&OFIFG); // Test oscillator fault flag__bis_SR_register(SCG0); // Disable the FLL control loopUCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operationUCSCTL2 |= 243; // Set DCO Multiplier for 8MHz// (N + 1) * FLLRef = Fdco// (243 + 1) * 32768 = 8MHz__bic_SR_register(SCG0); // Enable the FLL control loop// Worst-case settling time for the DCO when the DCO range bits have been// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx// UG for optimization.// 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle__delay_cycles(250000);//3)看门狗定时器初始化WDTCTL =(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL0+WDTIS_4);//1S周期看门狗定时器_EINT();//Enable all the Interruptionwhile(1){SFRIE1 |= WDTIE; //Enable WDT Interrupt and Osc Fault IO_Text_L1; //休眠前IO置低LPM3; //MCU进入休眠模式3 IO_Text_H1; //唤醒后IO置高__delay_cycles(100); //Delay}}
#pragma vector=WDT_VECTOR__interrupt void watchdog_timer (void){LPM3_EXIT;// Clear CPUOFF bit from 0(SR) _BIS_SR(LPM3_bits) ; return;}
Lina Lian:
回复 pengpeng:
peng peng,
看你的应用,应该是UCS, PMM部分出问题了。你没有用TI的core library,你那个是MSP430Ware中的例程,关于FLL, PMM, TI也提供了‘MSP430F5xx and MSP430F6xx Core Libraries’来帮助用户简化控制,请从http://www.ti.com/lit/zip/slaa448下载源代码,并从网上下载对应文档。
你先换成core library控制试试,如果还有同样现象,试着把SVSH, SVSL, SVMH, SVSH分别disable掉试试,看看哪种组合可以不再使MCLK飘升。
pengpeng:
回复 Lina Lian:
好的,谢谢,我先试试。
今天测试,发现唤醒后加入了这条指令__bis_SR_register(SCG0); ,多次唤醒后MCLK就不会再出现升高的现象,但是频率不是很准了每次只有6Mhz左右。
SCG0位好像是关闭FLL功能的,似乎就是FLL使用不当造成的。
while(1) { SFRIE1 |= WDTIE; //Enable WDT Interrupt and Osc Fault IO_Text_L1; //休眠前IO置低 LPM3; //MCU进入休眠模式3 __bis_SR_register(SCG0); //置1IO_Text_H1; //唤醒后IO置高 __delay_cycles(220); //Delay }