This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5509 偶尔会产生XT1 fault

Other Parts Discussed in Thread: MSP430F5509, CC1101

问题描述:

1. MSP430F5509+CC1101在实现定时发送无线数据包的功能时,偶尔会产生XT1 fault。

2. 取100个设备进行测试,在运行一段时间后,大约会有7个设备产生了XT1 fault。

3. 使用数字电源,串联30欧姆电阻,为设备供电,每一个设备都会产生XT1 fault。

4. XT1 fault产生的时间,是在CC1101发送数据包完成后的瞬间,接收端可以收到此数据包。

5. 将程序中的所有的__bis_SR_register(LPM3_bits + GIE);更改为__bis_SR_register(LPM0_bits + GIE);,仍然会出现XT1 fault。

6. 去除程序中所有的__bis_SR_register(LPM3_bits + GIE);,稍作修改,使得程序可以实现预定功能,未出现XT1 fault。

注:

1. MCLK = DCODIV = 12MHz, SMCLK = DCODIV = 12MHz, ACLK = XT1 = 32.768KHz, FLL reference = XT1CLK

2. CC1101发送数据包时,设备的总电流大约40mA,耗时10ms。

3. XT1 = 32.768KHz外部晶振,  -20 < PPM < 20, LF mode

求助:

1. 什么情况下可以产生XT1 fault ?

2. 产生XT1 fault后,需要进行哪些操作,使得系统可以尽快回到正常工作状态?

UCS的设置函数:

/*******************************************************************************
 * @fn:			InitSysClk_12MHz
 * @brief:		MCLK = SMCLK = DCOCLKDIV = 12MHz, ACLK = XT1CLK = 32.768KHz
 * @para:		none
 * @return:
 * 		         0 = ok
 * 		        -1 = XT1 error
 * 			-2 = DCO error
 * 			-3 = XT1 error && DCO error
 * 			-4 = XT2 error
 * 			-5 = XT1 error && XT2 error
 * 			-6 = DCO error && XT2 error
 * 			-7 = XT1 error && DCO error && XT2 error
 ******************************************************************************/
signed char InitSysClk_12MHz(void) {

	signed char rc = 0;

	*Address = 0x9628;
	*(Address + 4) = 0x0800;
	*Address = 0x9600;

	P1SEL |= BIT0;
	P1DIR |= BIT0;

	P5SEL |= BIT4 | BIT5;                     // Select XT1

	UCSCTL6 &= ~(XT1OFF);                     // XT1 On
	UCSCTL6 |= XCAP_3;                        // Internal load cap
	UCSCTL3 = 0;                              // FLL Reference Clock = XT1

	// Loop until XT1,XT2 & DCO stabilizes - In this case loop until XT1 and DCo      
        // settle unsigned int delay = 60000;

	do {
		UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
		// Clear XT2,XT1,DCO fault flags
		SFRIFG1 &= ~OFIFG;                      // Clear fault flags
		if (--delay == 0) {
			if (UCSCTL7 & XT1LFOFFG) {	// XT1 error
				rc += -1;
			}
			if (UCSCTL7 & DCOFFG) {		// DCO error
				rc += -2;
			}
			if (UCSCTL7 & XT2OFFG) {	// XT2 error
				rc += -4;
			}
			return rc;
		}
	} while (SFRIFG1 & OFIFG);              // Test oscillator fault flag

	UCSCTL6 &= ~(XT1DRIVE_3);       // Xtal is now stable, reduce drive strength

	UCSCTL4 |= SELA_0;                      // ACLK = LFTX1 (by default)
	UCSCTL3 = SELREF_0;                     // Set DCO FLL reference = REFO
	UCSCTL0 = DCO0 | 0x0000;             	// Set lowest possible DCOx, MODx

	__bis_SR_register(SCG0);
	// Disable the FLL control loop

	UCSCTL1 = DCORSEL_5;                    // Select DCO range 16MHz operation
	UCSCTL2 = FLLD_0 + 365;                 // Set DCO Multiplier for 8MHz
											// (N + 1) * FLLRef = Fdco
											// (365 + 1) * 32768 = 12MHz
	__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 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle
	__delay_cycles(375000);

	// Loop until XT1,XT2 & DCO fault flag is cleared
	delay = 60000;
	do {
		UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
		// Clear XT2,XT1,DCO fault flags
		SFRIFG1 &= ~OFIFG;                      // Clear fault flags
		if (--delay == 0) {
			if (UCSCTL7 & XT1LFOFFG) {			// XT1 error
				rc += -1;
			}
			if (UCSCTL7 & DCOFFG) {				// DCO error
				rc += -2;
			}
			if (UCSCTL7 & XT2OFFG) {			// XT2 error
				rc += -4;
			}
			return rc;
		}
	} while (SFRIFG1 & OFIFG);                   // Test oscillator fault flag

	PMMCTL0_H = PMMPW_H;                // PMM Password
	SVSMHCTL &= ~(SVMHE | SVSHE);         // Disable High side SVS
	SVSMLCTL &= ~(SVMLE | SVSLE);         // Disable Low side SVS

	return 0;
}
  • 你好!

    请试一下将XT1的驱动电流XT1DRIVE维持在11下,是否还会出现这个问题,在你的代码里,把如下语句注释掉即可

    UCSCTL6 &= ~(XT1DRIVE_3);       // Xtal is now stable, reduce drive strength

    XT1 fault后需要软件清除以恢复。

    另外XT1 fault后XT1的时钟源会自动切换到REFO,内部的32768HZ晶振继续运行。

  • 也可以用示波器观察一下电路的电压变化,一般射频ic在发送无线信号时工作电流会增加,如果供电不足有可能造成电压波动,从而影响到整个系统

  • 在把最后一个数据包放到Buffer中后,delay一段时间再进低功耗,是否有改善?

  • Hardy Hu:

    你好!我有两个问题请教一下:

    1. 如何根据自己的运行环境来确定UCSCTL6.XT1DRIVE的配置?MCLK=DCODIV=12MHz,SMCLK=DCODIV=12MHz,ACLK=XT1=32.768KHz,FLLREF=XT1=32.768KHz,这样的环境下,能否将UCSCTL6.XT1DRIVE配置为0,00b = Lowest current consumption for XT1 LF mode. XT1 oscillator operating

    range in HF mode is 4 MHz to 8 MHz.

    2. 我做了两个测试:初始化ACLK=XT1=32.768KHz。 一、在产生XT1 fault,未清除此fault的情况下,测得ACLK=33KHz。二、在产生XT1 fault,清除此fault的情况下,测得ACLK=32.768KHz。注:测试得:REFO = 33KHz,XT1=32.768KHz。这是否可以说明,在产生XT1 fault后,ACLK=REFO=33KHz,然后在清除XT1 fault后,ACLK又回复到了之前的状态,ACLK=XT1=32.768KHz?

  • dirtwillfly :

    你好!

    初步测试,在射频IC发送无线信号时,工作电流在36mA与40mA之间。

    如何来判断是不是供电不足引起的XT1 fault?XT1平稳工作又需要怎样的一个电气环境?电压抖动范围是多少?电流抖动范围是多少?

  • HG:

    你好!

    有几个情况,我再补充一下:

    1. 并不是每次发送后都会产生XT1 fault。

    2. 并不是所有的设备都会产生XT1 fault。

    3. 使用新电池短时间内并不会产生XT1 fault。

    问题:

    1. 你所说的将数据包放到buffer,是指将数据包放入CC1101的TX FIFO中吗?发送数据包之前?还是说发送数据包完成之后?

    2. delay一段时间是为了让CC1101完成数据包的发送吗?

  • 你好!

    1.XT1DRIVE的参数是按照晶体的频率来确定,32.768KHZ用00b就可以了

    2.是的,可以这样理解。

  • Hardy Hu:

    你好!

    1. 我代码中有一句“UCSCTL6 &= ~(XT1DRIVE_3);”,这说明我使用的配置是UCSCTL6.XT1DRIVE = 0,而我的XT1连接的是32.768KHz。也就是说,此处的配置是比较合理的。

    2. 今天我将配置更改为UCSCTL6.XT1DRIVE = 2, 系统的待机功耗增加了0.4uA,晶振的PPM出现了微小的变化(不过PPM的绝对值仍然是低于20),然后继续做测试,发现还是有一些设备产生了XT1 fault。

  • 晶振fail 一般以硬件问题为主吧,几种比较常见的:

    1 电源和GND纹波过大

    2 外部静电冲击

    3 驱动功率不足或过大,晶振spec里有驱动功率是< 100 mw这样的,过小会不能启振,多大会驱动成方波稳定性不好。

    4 外部匹配阻抗和电容参数不合适,这个是滤波的,比较好的波形是正弦波,滤波不好会有谐振和过冲。