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.

[参考译文] LP-MSPM0L1306:转换启用 ADC 后、Re 结果不正确。 ADC 由比较器事件触发。

Guru**** 2465890 points
Other Parts Discussed in Thread: LP-MSPM0L1306, SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1460185/lp-mspm0l1306-incorrect-adc-result-after-re-enable-conversion-adc-is-triggered-by-comparator-event

器件型号:LP-MSPM0L1306
主题中讨论的其他器件: SysConfig

工具与软件:

尊敬的 TI:

 

我正在尝试使用比较器输出来触发 ADC 采样。 此部件正常工作。 但我需要在应用期间的特定时间禁用采样功能。 当重新启用采样回时、ADC 对不正确的结果进行采样。

以下是如何在 LP-MSPM0L1306上复制此问题。

 

SysConfig (请参阅随附的照片):

使用 PWM 在 PA3上生成1kHz、50%占空比方波

设置比较器、以将 PA26用作正输入、内部电压基准作为负输入。 使用 DL_COMP_EVENT_OUTPUT_EDGE 生成事件信号以触发 ADC

将 ADC 设置为事件触发器、单次转换、禁用重复模式、对 PA15进行采样

连接到比较器正输入和 ADC 通道。

 

将板载 PA3、PA15、PA26连接在一起

 

在调试模式下运行附加的代码、该代码应在5秒后停止、ADC_RAW 缓冲区将填充3300。 这是正确的、因为当 ADC 采样时、PWM 处于逻辑高电平。

 

#include "ti_msp_dl_config.h"
#include "main.h"


volatile uint16_t adc_raw[32];
volatile uint8_t debugCnt=0;

void record_ADC_res(){
    uint16_t res = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
    adc_raw[debugCnt]=res*3300/1023;
    debugCnt++;
    if(debugCnt>=32) {
        debugCnt=0;
        __BKPT();
    }
}
bool adcTriggered=false;
int main(void)
{
    SYSCFG_DL_init();
    for(uint16_t i=0;i<5000;i++){
        delay_cycles(32000);//1ms delay
    }
    DL_COMP_enableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
    DL_ADC12_enableConversions(ADC12_0_INST);
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    while (1) {
        if(adcTriggered){
            adcTriggered=false;

            record_ADC_res();
            //DL_COMP_disableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
            //delay_cycles(32*1500);
            //DL_COMP_clearEventsStatus(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
            //DL_COMP_enableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
            DL_ADC12_enableConversions(ADC12_0_INST);

        }

    }
}

void ADC12_0_INST_IRQHandler(void)
{
        switch(DL_ADC12_getPendingInterrupt(ADC12_0_INST))
        {
        case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
            adcTriggered=true;
            break;
        }
}

然后、取消"delay_cycles (32*1500);"的注释。 这会模拟禁用采样、因为只有在这个延迟之后才会启用 ADC 转换。

当运行代码时、您可以看到结果有时会变为逻辑0。

 

我的问题是:

  1. 是什么导致 ADC 采样的值错误?
  2. 如何正确配置 ADC、比较器或事件、以便在 重新启用采样后采样结果仍然正确

请注意、我无法使用 PWM 来触发 ADC、因为 PWM 只是为了模拟外部信号、以便于排除故障。

我使用的是 CCS 12.8.1、SysConfig 1.21.0、SDK 2.2.0.05

感谢您的及时响应。 谢谢!

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

    您是否禁用并重新启用了事件? 实际上、我想您应该直接观察寄存器。

    例如、使用 IO (而不是 PWM)触发(进行测试)、

    1. 首先重新启用断点后、观察寄存器
    2. 然后是 IO 触发器、
    3. 然后再次断点、 再次观察寄存器
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已尝试通过第33和35行启用和禁用事件。 结果是相同的。
    我将尝试 IO 方法。
    是否有任何寄存器我也应该额外注意?
    所有寄存器都可以从"寄存器"窗口中看到、对吧?

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

    我已经移除了 PWM、仅将 PA15、PA26连接在一起、通过一个接地电容器来消除开关去抖、并通过一个开关连接到3V3。

    可以观察到 ADC 和 COMP 的寄存器值

    第一个实验  
    第0步:断点位于 line37、我在开关关闭(电压为0V)时开始调试、但调试器仍以某种方式在第37行停止。

    步骤1:然后我恢复(F8)、程序仅在我打开开关后停止。 更改如下:ADC0_SVT_MEMRES[0]、 ADC0_SVT_FIFODATA、COMP0_STATE 变为高电平、ADC_CTRL0.ENC 从开启更改为关闭

    步骤2:然后我恢复(F8)程序仅在之后停止、 直到我第二次关闭并打开开关。  ADC0_SVT_MEMRES[0]、ADC0_SVT_FIFODATA 只有轻微变化  

    步骤3:然后 当程序仍然停止时、我第三次关闭和打开开关、然后 恢复(F8)、程序立即再次停止、 只 对 ADC0_SVT_MEMRES[0]、ADC0_SVT_FIFODATA 略有变化。  

    第一个实验似乎证明、即使  未选中 SysConfig 中的"Repeat mode"复选框、ADC 也不会自动禁用。

    第二个实验
    与第一个实验类似、但启用了第33、35、36行、将断点更改为第35行。 第0步至第3步会生成相同的结果。  

    第二个实验似乎证明了禁用和清除事件不会停止触发 ADC

    看起来 ADC 无论如何都在不断触发

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

    您需要更改触发模式。

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

    我将触发模式更改为"有效的触发器将步进到下一个存储器转换寄存器"、其余部分与实验2相同。 第0步至第3步会产生相同的结果。 还有其他可以尝试的东西吗?

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

    您好、您好、有任何更新吗?  

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

    很抱歉我的回复晚了、请让我进行测试、我很快就会提供反馈。

    对于您的问题、您是说您更改了触发模式、但 ADC 仍在 继续触发(未启用重复模式)?

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

    我没有更改触发模式。 我只想暂时禁用"比较器事件触发器 ADC"、并在重新启用后获得正确的 ADC 结果。 我现在看到的是、禁用事件或 ADC 转换后、ADC 仍然错误触发。

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

    您好、

    我使用您的代码测试了 LaunchPad、但测试结果看起来不错。

    #include "ti_msp_dl_config.h"
    //#include "main.h"
    
    
    volatile uint16_t adc_raw[32];
    volatile uint8_t debugCnt=0;
    
    void record_ADC_res(){
        uint16_t res = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
        adc_raw[debugCnt]=res*3300/1023;
        debugCnt++;
        if(debugCnt>=32) {
            debugCnt=0;
            //__BKPT(0);
        }
    }
    volatile bool adcTriggered=false;
    int main(void)
    {
        SYSCFG_DL_init();
    //    for(uint16_t i=0;i<5000;i++){
    //        delay_cycles(32000);//1ms delay
    //    }
        DL_COMP_enableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
        DL_ADC12_enableConversions(ADC12_0_INST);
        NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
        DL_ADC12_startConversion(ADC12_0_INST);
        while (1) {
            if(adcTriggered){
                adcTriggered=false;
    
                record_ADC_res();
                DL_COMP_disableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
                delay_cycles(32*1500);
                DL_COMP_clearEventsStatus(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
                DL_COMP_enableEvent(COMP_0_INST, (DL_COMP_EVENT_OUTPUT_EDGE));
                DL_ADC12_enableConversions(ADC12_0_INST);
                DL_ADC12_startConversion(ADC12_0_INST);
            }
    
        }
    }
    
    void ADC12_0_INST_IRQHandler(void)
    {
            switch(DL_ADC12_getPendingInterrupt(ADC12_0_INST))
            {
            case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
                adcTriggered=true;
                break;
            default:
                break;
            }
    }
    

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

    对代码进行了一次修改。

    易失性 bool adcTriggered=false;

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

    这是我的 syscfg 文件。 使用"有效触发器将单步执行至下一个存储器转换寄存器"

    e2e.ti.com/.../comp_5F00_dac_5F00_to_5F00_timer_5F00_event.syscfg

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

    您似乎上传了错误的 SysConfig 文件。 它不包含任何关于 ADC 的信息。

    下面是我的项目、它复制了这个错误。 如果将 PA3、PA15、PA26连接在一起、请移除 J1和 J12上的跳线、不涉及其他外部电路元件。 运行该工程7秒、它应该会停止并显示在3300mV 和0V 之间跳跃的 ADC_RAW 记录值。

    在本项目中、我已实施了您的以下建议:" 易失性  bool adcTriggered=false;"和"valid trigger will step to next memory conversion register"

    如果我们的结果不同、那么也许我们可以开始对硬件差异进行故障排除

    e2e.ti.com/.../min_5F00_adc_5F00_debug.zip

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

    e2e.ti.com/.../adc12_5F00_single_5F00_conversion.syscfg

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

    快速问题:COMP 的事件是"比较器输出的上升沿或下降沿"。 因此、对于 PWM、它将在上升沿和下降沿触发 ADC。 如果您也将 ADC 连接到 PWM、ADC 将首先对 PWM 的高电平(3.3V)、然后对低电平(0V)、然后再次对高电平(3.3V)进行采样...

    对吗?

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

    否、由"比较器输出的上升沿或下降沿(由 IES 位选择)"触发。 在本例中、它是上升沿。 如果您移除第67行的延迟、则可以看到系统在上升沿持续触发

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

    是的、我在电路板中重现了问题。 似乎当事件被禁用时、COMP 仍会 在 RIS 中设置 COMPIFG、并且在调用 clearEventsStatus 时、它不起作用。 因此、当您启用比较事件时、它会立即触发 ADC。

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

    让我向我的团队了解根本原因。 我不知道为什么 ICLR 寄存器不起作用。 对于临时的权变措施、您认为禁用整个比较器是可以的吗?

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

    很高兴听到您能够复制错误!
    除了关闭整个比较器外设之外、是否可以推荐一些禁用功能? 因为我们有时序限制  

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

    对于该问题、我的团队正在解决该问题、我们需要更多时间来找到更好的解决方法。  

    关于您的问题、我想您可以尝试为比较器重新配置多路复用器、而不是重新初始化整个 比较器。 你怎么看?

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

    请尝试按照以下步骤 重新启用 COMP。

      • 当需要启用 COMP 时、
        • DL_COMP_setPublisherChanID (COMP_0_INST、0);//删除实际的发布者
        • DL_COMP_enableEvent (COMP_0_INST、(DL_COMP_EVENT_OUTPUT_EDGE));//在 IMASK 中启用 COMP 事件
        • DL_COMP_ENABLE (COMP_0_INST);//启用 COMP 模块
        • DL_COMP_disableEvent (COMP_0_INST、(DL_COMP_EVENT_OUTPUT_EDGE));//通过在 IMASK 中清除来禁用 COMP 事件
        • DL_COMP_setPublisherChanID (COMP_0_INST、COMP_0_INST_PUB_CH);//配置实际的发布者
        • DL_COMP_enableEvent (COMP_0_INST、(DL_COMP_EVENT_OUTPUT_EDGE));// IMASK-ENABLE Re 事件
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢! 它似乎在演示工程上有效。 我很快就会在实际项目中尝试它。