具有不同步进源的 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
中的初始触发器)。
我正在尝试使用相同的序列器测量一些 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
中的初始触发器)。