具有不同步进源的 Tiva ADC 定序器

Tiva ADC Sequencer with different step sources

我正在尝试使用相同的序列器测量一些 ADC 通道。我以 Texas Tiva's ARM Cortex-M4 Workshop 的第 5 章为基础。所以,我的(中断的)原始代码运行完美:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"

uint32_t ui32ADC0Value[4];

volatile uint32_t ui32TempAvg;
volatile uint32_t ui32TempValueC;

int main(void) {

    SysCtlClockSet(
    SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_SYSDIV_5);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);

    ADCSequenceDisable(ADC0_BASE, 1);
    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinTypeADC(GPIO_PORTD_BASE,
    GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_TS);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

    IntEnable(INT_ADC0SS1);
    ADCIntEnable(ADC0_BASE, 1);
    ADCSequenceEnable(ADC0_BASE, 1);

    IntMasterEnable();

    while (1) {
        ADCProcessorTrigger(ADC0_BASE, 1);
    }

}

void ISRHandler(void) {

    while (!ADCIntStatus(ADC0_BASE, 1, false)){};

    ADCIntClear(ADC0_BASE, 1);
    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);

    ui32TempAvg = ui32ADC0Value[3];

    ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096) / 10;

}

但是如果我改变这部分

ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_TS);
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_TS);
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_TS);
ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
        ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

通过这部分(因此步骤 0 到 2 读取其他通道,而不是 ADC_CTL_TS),其中我的模拟引脚通道 接地 (因此测量将读数接近于零):

ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7);
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
        ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

第 3 步(我测量的地方 ADC_CTL_TS)变得疯狂,范围值完全不连贯。此外,查看调试,通过其他步骤,TS 的测量值看起来像 "walking",因为当其中 3 个接近 0 时,另一个 "moving one" 大得多。它看起来像是时间错位。

为什么,以及如何解决?谢谢

Tiva C 的 ADC 定序器正在将样本读入专用 FIFO,不同定序器的深度不同。在您的情况 (SS1) 中,FIFO 深度为 4。现在让我们看看如何触发 ADC。您是主循环中的 运行 ADCProcessorTrigger,没有任何延迟或与 ADC 的读取同步,甚至没有检查之前的转换是否已完成。因此,随着样本的传入,它们总是 "pushing out" 来自 FIFO 的先前样本,并且 FIFO 很容易失去同步(例如,来自通道 i 的样本将被转移到先进先出,甚至推出。)。所以正确的方法是在FIFO中的数据被完全读取后触发转换,并且在中断中完成。所以我建议将 ADCProcessorTrigger 部分放在中断处理程序的末尾附近(以及 main 中的初始触发器)。