简体   繁体   English

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

[英]Tiva ADC Sequencer with different step sources

I'm trying to measure some ADC channels with the same sequencer. 我正在尝试用相同的音序器测量一些ADC通道。 I took a base on the Chapter 5 of Texas Tiva's ARM Cortex-M4 Workshop . 我在Texas Tiva的ARM Cortex-M4研讨会的第5章中找到了基础。 So, my (interrupted) original code is working perfectly: 所以,我(中断的)原始代码完美运行:

#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;

}

However if I change this part 但是,如果我改变这部分

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);

by this part (so the steps 0 to 2 read other channels, instead of ADC_CTL_TS), where my analog pin channels are grounded (so the measurement would read near zero): 通过这部分(所以步骤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);

the step 3 (where I measure ADC_CTL_TS) goes crazy, ranging values totally incoherent. 第3步(我测量ADC_CTL_TS)变得疯狂,测试值完全不连贯。 Also, looking into debug, the measurement of TS looks like "walking" throught the other steps, because when 3 of them are near 0, the other "moving one" is far bigger. 另外,考虑到调试,TS的测量看起来像是“走”通过其他步骤,因为当其中3个接近0时,另一个“移动的”要大得多。 It looks like a temporal misalignment. 它看起来像是一个暂时的错位。

Why, and how to fix it? 为什么,以及如何解决它? Thanks. 谢谢。

The Tiva C's ADC sequencer is reading the samples into a dedicated FIFO, which has different depth for different sequencers. Tiva C的ADC序列发生器正在将样本读入专用FIFO,该FIFO具有不同深度,适用于不同的序列发生器。 In your case (SS1) the FIFO depth is 4. Now let's look how you trigger the ADC. 在您的情况下(SS1),FIFO深度为4.现在让我们看看如何触发ADC。 You are running the ADCProcessorTrigger in your main loop, without any delay or synchronization with the reading of the ADC, even without checking the previous conversion is done. 您正在主循环中运行ADCProcessorTrigger ,即使没有检查先前的转换也没有任何延迟或与ADC读取同步。 So, as the samples are incoming, they are constantly "pushing out" the previous samples from the FIFO, and the FIFO easily getting out of sync (eg the sample from channel i will be displaced to some other place in the FIFO, or even pushed out.). 因此,当样本进入时,它们不断地从FIFO中“推出”先前的样本,并且FIFO很容易失去同步(例如,来自通道i的样本将被移位到FIFO中的其他位置,甚至推出。)。 So the correct way would be to trigger the conversion AFTER the data from the FIFO is read completely, and it is done in the interrupt. 因此,正确的方法是在完全读取FIFO的数据后触发转换,并在中断中完成。 So I recommend putting ADCProcessorTrigger part near the end of the interrupt handler (and an initial trigger in main ). 所以我建议将ADCProcessorTrigger部分放在中断处理程序的末尾附近(以及main的初始触发器)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM