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.

[参考译文] MSP430F5437A:ADC 偶尔出现意外值。

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/879878/msp430f5437a-occasional-unexpected-values-from-the-adc

器件型号:MSP430F5437A

我们在 ADC 上使用3个通道。 一个用于温度读取、一个用于电池电平、另一个用于环境光电平。 有时、我们会看到 ADC 值是意外的。 例如、温度值与之前的温度相距10度。 或者电池电量将从70-80%下降到30-40%。 在大多数情况下、它按预期工作。

由于这是一个电池器件、我们将 MSP430置于 LMP3低功耗模式。 我们将在进入睡眠模式之前关闭 ADC 以降低电流。 当微控制器唤醒时、我们会在读取温度或电池之前重新初始化 ADC。 我在上一篇文章中读出、我们应该在 进行任何更改之前清除控制寄存 器、即 ADC12CTL0 = 0;不同 MSP 除外。 ()我猜它也会抑制 MSP 的其他变体。 有人能解释为什么我们应该在进行任何更改之前将其清除? 这是否会导致偶尔出现意外的 ADC 值?

我在下面发布了我们用于参考的代码。



/** * initial_adc_sensor */ void initialize_adc (t_adc * adc、 const t_io_pin * nref、 const t_io_pin * sensor) { adc->pos_reference = pref; adc->neg_reference = nref; adc-> sensor = sensor; /* init/* IOS *(adc->pos_reference->port->selection)|=(adc->pos_reference->bit); //*(adc->neg_reference->port->selection)|=(adc->neg_reference->bit); //* adc->pos_reference->port |= adc-> 初始 化 io_pin、pin (pos_reference->pin);// 初始化 io_pin、ini_state_pin、ine_pin (pin、sensor_pin、in_reference-pin) 三态); // if (!read_pin (get_gpio (IO_V_24AC))) //initialize_IO_Pin (get_GPIO (IO_BATT_EN)、高电平); //否则 初始化_IO_Pin (GET_GPIO (IO_BATT_EN)、TRISTATE); // *初始化 ADC */ REFCTL0 = 0; // ADC12_A 参考控制寄存器 ADC12CTL0 = ADC12REFON+ADC12REF2_5V+ADC12ON+ADC12MSC+ADC12SHT0_15;//打开 ADC12,延长采样时间 //避免结果溢出 ADC12CTL1 = ADC12SHP+ADC12CONSEQ_3; //使用采样计时器、单序列 ADC12CTL2 |= ADC12TCOFF+ADC12REFOUT+ADC12PDIV;//将时钟除以4以减慢 ADC 采样 ADC12MCTL0 = ADC12SREF_7 | ADC12INCH_0;// ADC A0 -停止在 A0 | ADC12EOS ADC12MCTL1 = ADC12SREF_7 | ADC12INCH_4 | ADC12EOS // ADC A5 -在 A5处停止| ADC12EOS ADC12CTL0 |= ADC12ENC; //启用转换 ADC12CTL0 |= ADC12SC; //开始转换-软件触发器 ADC_WAKE_UP (ADC); ADC_RESET (ADC); ADC12IE = ADC12IE0 | ADC12IE1; //启用 ADC12IFG.0、1、4 // ADC12IE = 0x13; //启用 ADC12IFG.0、1、4 }
/**
* ADC_WAKE_UP
*/
void
ADC_WAKE_UP (t_ADC * ADC)
{
ENTER_CRITAL ();

//
*定时器配置
*
断言((TA1CTL 和0xFFe)= 0x0);

TA1CTL = tassel_SMCLK | ID0 | ID1;/*使用 SMCLK 作为时钟源*/*


定时器事件捕捉配置
*/
TA1CCTL1 = OUT |/*OUT 位值*/
CAP |/*设置为捕获模式*/
CCIS0 |/*捕获输入 CCIxB = CBOUT ->
*数据表第28页*/
SCS |/*将比较器信号同步至
*定时器时钟*/
CM1;//在上升沿捕捉*/

断言(!(TA1CTL & MC__UP);

exit_critical ();
}
/**
*当系统从低功耗中退出时调用。
//
void
thermistor_wakeup (t_thermistor * thr)
{
//
* init ios
*/
initialize_io_pin (thr->adc-> sensor、tristate);
initialize_io_pin (get_gpio (io_ALS _pin)、tristate);

adc_wake_up (thr->adc);

ADC_RESET (THR->ADC);
delay10ms (5);
ADC12CTL0 = ADC12REFON+ADC12REF2_5V+ADC12ON+ADC12MSC+ADC12SHT0_15;//打开 ADC12、延长采样时间
ADC12CTL0 |= ADC12ENC; //启用转换
ADC12CTL0 |= ADC12SC; //开始转换-软件触发
delay10ms (1);
ADC12IE = 0x13; //启用 ADC12IFG.3
}

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

    ADC_RESET()有什么作用?

    我在这里看到的危险是、当 CONSEQ=3且 MSC=1时、设置 ENC=0不会立即停止 ADC [参考用户指南(SLAU208Q)第28.2.7.6节]。 如果您在转换仍在运行时设置 REFON=0、我怀疑您会得到错误的读数。  

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

    你(们)好  

    您的问题是否已得到解决?

    伊斯天

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

    不、但我没有时间对此进行研究、因为我一直在从事另一个项目。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉、忘记添加这个。 关于停止转换的好一点。 我目前正在进行另一个项目、但会尝试一下、看看它是否有用。 


    /** * ADC_RESET */ void ADC_RESET (t_ADC * ADC) { ENTER_CRITAL (); TA1CCTL1 = 0;//清除捕捉配置 TA1CTL = 0;//关闭计时器 A //* 禁用所有中断(清除标志) */ TA1CCTL1 &&~CCIE;//禁用捕捉中断* TA1TIE 和 TA1CTL =~/*禁用计时器中断*/ TA1CTL &=~TAIFG;/*清除中断标志*/ TA1CCTL1 &=~CCIFG;/*清除中断捕捉标志*/ //* 复位 ADC 状态机 */ ADC->status = SAMPLE_UNDEF; ADC->state = ADC_IDLE; assert (!(TA1CTL & MC_UP) ;EXIT_EXIT) ;_ CRIT_UP)

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

    祝你好运。

    伊斯天