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.

[参考译文] CCS/MSP430G2553:使用WDT作为从LPM3唤醒的计时器时,内部Vref=2.5V的ADC不工作

Guru**** 2589280 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/630106/ccs-msp430g2553-adc-with-internal-vref-2-5v-not-working-when-using-wdt-as-timer-for-waking-up-from-lpm3

部件号:MSP430G2553

工具/软件:Code Composer Studio

大家好,  

我正在编写一个程序,其中MSP430大部分时间都在LPM3上,并且它每隔4秒就会通过WDT中断被WDT唤醒。  

从WDT的ISR转到LMP0,然后必须读取模拟输入,然后再次转到LMP3。 当我使用具有VCC的ADC作为参考时,该程序正在工作,配置如下:

ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE;// ADC10ON,中断已启用
ADC10CTL1 = inch_7;//输入A7
ADC10AE0 |= 0x80;// PA.ADC 1.7 选项选择

然后在无限时:

ADC10CTL0 |= ENC + ADC10SC;//开始采样和转换
__bis_sr_register (CPUOFF + GIE);// LPM0,ADC10_ISR将强制退出
ADC_Result = ADC10MEM;

我的问题是,现在我想使用ADC,但在内部Vref=2.5V的情况下,它不工作(看起来WDT不工作,它不再唤醒系统)。 使用WDT作为计时器来唤醒系统与使用内部电压发生器作为ADC内部参考是否存在不相容性?

BES

下面是我正在尝试的代码:

#include <MSP4S.h>

#define clock 4. //wake up interval in seconds-1


int wake up sec=clock; //初始唤醒时钟。



内部主菜单(void)
{
BCSCTL1|= DIVA_0; // ACLK/1
BCSCTL3 |= XCAP_3; //12.5pF CAP- 3.2768万Hz晶振
WDTCTL的设置= WDT_ADLY_1000; // WDT 1S/4间隔计时器
IE1 |= WTIE; //启用WDT中断
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + Ref2_5V+ ADC10ON + ADC10IE;// ADC10ON,Vref在2.5V时打开,启用中断
__enable_interrupt (); //启用中断。
TCCR0 = 30; //延迟以允许Ref结算
TACTL0 |= CCIE; //比较模式中断。
TACTL = Tassel_2 | MC_1; // TALCK = SMCLK,向上模式。
LPM0; //等待延迟。
TACTL0 &=~CCIE; //禁用计时器中断
__disable_interrupit();
ADC10CTL1 = inch_7; //输入A7
ADC10AE0 |= 0x80; // pa.adc 1.7 选项选择
P1DIR = 0xFB; //除WFP 1.2 输入
P1OUT = 0外的所有P1.x输出; //所有P1.x重置
P1REN = 1; //所有P1.x电阻器拉出U/D启用
P2DIR = 0xF7; //除WFP 2.3 (日信号)之外的所有P2.x输出,因为输入
P2OUT = 0; //所有P2.x重置
P2REN = 1; //所有P2.x电阻器拉取U/D启用
P1IE=0; //所有P1端口中断在

(1)
{

如果(P2IN=0x08) //如果日信号打开
{
//不执行任何操作
}
否则
{
//读取ADC
ADC10CTL0 |= ENC + ADC10SC; //开始采样和转换
__bis_sr_register (CPUOFF + GIE); // LPM0,ADC10_ISR将强制退出 

如果(ADC10MEM < 0x88)//  
P1OUT =~0x01;//清除WFP 1.0 LED熄灭
否则
P1OUT |= 0x01;//将WFP 1.0 LED设置为打开

}
__bis_sr_register(LPM3_bits + GIE); //输入LPM3

}
}

#if defined(__TI_Compiler_version__)|| defined(__IAR_SYSTEMS _ICC__)
#pragma vector=WDT_vector
__interrupt void watchdog timer (void){

静态int c=0;
如果(c<wake Up秒)
{
C++;
}
否则
{
__BIC_SR_REGISTER_ON_EXIT (LPM3_bits);//从0 (SR)清除LPM3位
C=0;
}
}//

ADC10中断服务例程
#if defined(__TI_Compiler_version__)|| defined(__IAR_systems_ICC__)
#pragma vector=ADC10_vector
__interrupt void ADC10_ISR(void)
{__BIC_SR_register_on_exit(CPUOFF);
//从0(SR)
}清除CPUOFF位

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好BES,

    您是否能够在代码中设置断点,以便在代码不再响应之前查看其执行的最远的部分?  

    我仍在研究什么可能会阻止您的代码在主while循环中从低功耗模式唤醒。 问题之一似乎是在ADC测量之后,代码进入LPM3,这将禁用振荡器,包括监视程序计时器正在使用的振荡器。 尝试在ADC测量之后使用以下代码行进入LPM0:

    __bis_sr_register (LPM0_bits + GIE); //输入LPM0 

    以及更新在WDT中断中退出低功耗模式的代码行:

    __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//从0 (SR)清除LPM0位 

    此致,

    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Ryan:

    感谢您的回复。 我不能使用DE调试器,因为系统几乎总是在lpm3中输入,但我使用引脚作为标记,以通过硬件检查执行是否被卡住。 将ADC与内部电压发生器一起使用完全卡住,不执行while的第一行,并且显示的消耗比我在lpm3中遇到的消耗要高。

    如果ADC是参照VCC设置的,则代码在lpm3下运行良好,并且没有问题地唤醒,我使用的是带有外部振荡器的ackl,WDT工作正常。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    大家好,

    我想我找到了问题的根源。 《MSP430x2xx系列用户指南》中的表2.2 PAG 39。 在LPM3中,直流发电机关闭。
    这是因为我能够将ADC与内部直流发生器配合使用。 去LPM2可以保持直流发电机,看起来它在工作,虽然消耗量是10倍以上…(从20uA到200uA)至少在我的应用中。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好BES,

    这是否正是您正在运行的代码(必须省略Timer0_A0 ISR,但我猜它与ADC10 ISR完全相同)? 我提出这个问题是因为其中有几个问题可能导致未定义的行为:

    1.在32K晶体源ACLK实际启动之前,从ACLK计时WDT (这可能需要几百毫秒)。 请参阅2xx系列指南(SLAU144)的5.2 .7.1 部分。

    2.与评论相反,仅在WFP 1.1 和WFP 2.1 (BIT0)上启用下拉电阻器。 PxREN = 0xFF将启用全部。

    3.端口3保持浮动状态。 即使您的MSP具有20针封装,该端口仍存在于硅芯片上。 应按照2553数据表(SLAS735)引脚说明中所述启用下拉电阻器。

    在进一步调查之前,上述问题可能值得解决。 您也可以尝试从VLO (BCSCTL3|= LFXT1S_2)而不是32K晶体获取ACLK。

    如果低功耗很重要,您可以考虑不要始终启用2.5 V基准(REFON位)(在转换之间缓冲区自动关闭,但基准保持打开)。

    最后是关于计时器用法的说明:计数完成后,您可以停止计时器(MC_0)并节省一些电量。 不管怎样,虽然定时器+低功耗模式通常比延迟回路好得多,但使用定时器计算30个周期是超限的--所有定时器设置和定时器中断的维修都需要相当的时间。

    此致,

    Michal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Michal:  

    感谢您的回复。  您说的对,Timer0_A0 ISR被错过了,但我在代码中有它,就在ADC10_02示例中。  

    约1.在从ACLK计时WDT之前,请在之间进行延迟。 应该是这样的吗?

    BCSCTL3 |= XCAP_3; //12.5pF cap- 3.2768万Hz晶振
    __enable_interrupit()的设置; //启用中断。
    TCCR0 = 30; //延迟以允许ACLK结算
    TACTL0 |= CCIE; //比较模式中断。
    TACTL = Tassel_2 | MC_1; // TALCK = SMCLK,向上模式。
    LPM0; //等待延迟。
    TACTL0 &=~CCIE; //禁用计时器中断
    __disable_interrupt ();
    WDTCTL = WDT_ADLY_1000; // WDT 1S/4间隔计时器 

    对不起,在5.2 .7.1 部分中,此示例是在汇编器中完成的,我不是直接的。  

    约2和3。 好的建议,完成了,谢谢:)

    我更喜欢从32k晶体进行时钟,我需要优化消耗,而不是占地空间或成本。 我有经验,使用32k晶体的ACLK的LMP3要精确得多,VLO和消耗都很低。 由于在LPM3中内部直流发生器关闭,当要测量的信号低于VCC时,我在应用程序中设法不使用ADC,因此我可以使用VCC作为ADC的参考,并节省更多功率。  当然,您关于禁用REFON的建议可以很好地发挥作用,但从LPM2到上部模式。  

    关于您的计时器使用建议,我真的不知道您用MC_0来指哪个计时器? 我使用WDT作为第一个计时器,While完成,然后系统进入LPM3,由WDT唤醒,Make While (读取ADC,采取措施),然后再次进入睡眠状态。  可能是因为执行了一些涉及其他中断的操作,例如在某个时间内使用计时器在引脚中进行PWM,我想停止WDT,进行PWM脉冲,然后在完成后再次激活WDT。 这是正确的方法吗?

    无论如何,再次感谢您的建议。

    此致   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好BES,

    关于振荡器启动,C代码可能如下所示:

    Int StartupOsc (void)
    {
    int i;
    
    for (i =100; i !=0;--i)
    {
    IFG1 &=~OFIFG; //清除振荡器故障标志
    __DELAY周期(1万);//等待~10毫秒(~1 MHz时)
    如果((IFG1 & OFIFG)== 0)//未再次设置故障标志?
    返回0; //正常,振荡器正在工作
    }
    返回-1; // 100次后放弃(错误代码)
    }
    
    

    WDT应保持停止(WDTCTL = WDTPW | WDTHOLD | WDTTMSEL | WDTCNTCL或类似)并且在上述函数返回0之前不切换到ACLK。

    [报价用户="Green Power)]我更喜欢32k晶体的时钟,我需要优化消耗,而不是占用空间或成本。 我有经验,使用32k晶体的ACLK的LMP3要精确得多,VLO和消耗都很低。 由于在LPM3中内部直流发生器关闭,当要测量的信号低于VCC时,我在应用程序中设法不使用ADC,因此我可以使用VCC作为ADC的参考,并节省更多功率。  当然,您关于禁用REFON的建议可以很好地发挥作用,但从LPM2到上部模式。[/QUET]

    我建议只暂时尝试VLO,只是看看是否有任何变化。 您观察到异常行为,必须确定导致该行为的因素。

    Green Power 说:
    由于在LPM3中内部直流发生器关闭,当要测量的信号低于VCC时,我在应用程序中设法不使用ADC,因此我可以使用VCC作为ADC的参考并节省更多功率。[/QUOT]

    我不明白... 无论您是否测量,ADC输入(和任意引脚)处的任何信号都必须低于VCC (和高于VSS),否则会永久损坏芯片。

    无论如何,内部直流发生器与DCO (数字控制振荡器)相关,它似乎与ADC10的REF没有任何关系。

    Green Power 说:
    关于您的计时器使用建议,我没有真正了解您在MC_0中指的是哪个计时器?

    我的意思是在计时器A计数为30后停止计时器A并导致中断(TACTL = Tassel_2 | MC_0或等效代码,用于从“向上”模式切换到“停止”模式)。 否则在启用SMCLK时,它仍在计数(并消耗一些次要功率)。

    [引用user="Green Power)]可能是因为执行了一些涉及其他中断的操作,例如在特定时间内使用计时器在引脚中进行PWM,我想停止WDT,进行PWM脉冲,完成后再次激活WDT。 这是正确的方法吗?[/QUOT]

    是的,这听起来是一种合理的方法。

    此致,

    Michal