大家好、我尝试使用电路板上的两个 ADC 来对两个输入信号进行采样。 根据我使用单个 ADC 进行采样的经验、我能够构建的逻辑是、我使用相同的中断来触发两个 ADC 并开始同步转换。 在单个 while 环路中、我将对一个信号进行采样、获取另一个信号、并对其进行采样并结束转换。 我想我将面临的问题是抖动、因为在取和采样的指令周期中、可能会产生一些不准确的情况。 如何减少这种情况? 我是否也可以获得有关代码的指导?
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.
大家好、我尝试使用电路板上的两个 ADC 来对两个输入信号进行采样。 根据我使用单个 ADC 进行采样的经验、我能够构建的逻辑是、我使用相同的中断来触发两个 ADC 并开始同步转换。 在单个 while 环路中、我将对一个信号进行采样、获取另一个信号、并对其进行采样并结束转换。 我想我将面临的问题是抖动、因为在取和采样的指令周期中、可能会产生一些不准确的情况。 如何减少这种情况? 我是否也可以获得有关代码的指导?
您好、Soummyadeb、
如果您使用计时器、则可以设置 ADC 以相同的间隔进行采样、然后必须在采样完成后读取这些值。
请注意、计时器是该用例的硬性要求、因为这是一个单核 MCU、您必须依赖计时器来允许多个外设并排运行。
我们有一个项目可以让您参与其中、它只执行一个通道、并且还使用 DMA、您可以对其进行调整以更好地满足您的项目要求: e2e.ti.com/.../2084.ADCwDMA.zip
此外、还将始终存在一些抖动、MCU ADC 对于大多数应用而言是实用的、但其精度或速度不是专门设计的外部 ADC。 您需要确定结果上存在的抖动是否过大。
如果这确实是您的一个大问题、我建议您查看 TI 的 ADC 产品系列、并查找可满足您严格抖动要求的器件: www.ti.com/.../overview.html
// // // project0.c -演示最小 TivaWare 设置的示例 // //版权所有(c) 2012-2017 Texas Instruments Incorporated。 保留所有权利。 //软件许可协议 // //德州仪器(TI)提供此软件仅供 和//仅供 TI 的微控制器产品使用。 软件归 // TI 和/或其供应商所有,并受适用的版权 //法律保护。 您不能将此软件与"病毒"开源 //软件组合在一起以形成更大的程序。 // //此软件按“原样”提供,且存在所有故障。 //对于 本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何 //情况下、TI 不对任何 原因造成的特殊、意外或必然//损害负责。 // //这是 EK-TM4C123GXL 固件包版本2.1.4.178的一部分。 //// ***************** #include #include include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_adc.h" #include "inc/hw_types.h" #include "inc/hw_udma.h" #include "driverlib/driverlib" #driverlib/driver.h" #include "driverlib/driver.h"#driverlib#driverlib.driverlib.driver.h"#include "driverlib#driverlib/driverlib"#driverlib.driver.h"#include "driverlib.driver.h"#driverlib#driverlib.driverlib#driverlib.driver.h"#include "driverlib.driverlib.driverlib.driver.h"#include "driverlib.driverlib.driverlib.driver.h"#include "drivers.driverlib.driverlib.driverlib#driver.h"#include "drivers.driverlib#driverlib#driverlib.driver.h"#include "driver.h"#drivers. // //定义引脚到 LED 颜色映射。 //// ***************** // // //! \addtogroup example_list //!Project Zero (项目0)
//! //! 此示例演示了如何使用 TivaWare 设置时钟和 //! 切换 GPIO 引脚以使 LED 闪烁。 这是一个很好的开始 //开始的地方! 了解您的 LaunchPad 以及可用于对其进行编程的工具。 //// ***************** // // //如果驱动程序库遇到错误,则调用的错误例程。 //// ***************** #ifdef debug void __error__(char *dpcFilename、uint32_t ui32Line) { #endif //********* // ////主"C"语言入口点。 使用 TivaWare 切换 LED。 //// ***************** uint32_t adcbuffer[1000]; uint32_t adcdata1[1000]; uint32_t adcdata2[1000]; uint32_t i、timebase、triglvl、xpos、res0、res1; void main (){ SysCtlClockSet (SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);//20MHz 时钟 SysCtlPeripheralEnable (SYSCTL_Periph_ADC0); SysCtlPeripheralEnable (SYSCTL_Periph_ADC1); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF); GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3); GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_2); GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1); GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_4); ADCSequenceDisable (ADC0_BASE、3); //定时器配置 SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0); TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE); TimerLoadSet (TIMER0_BASE、TIMER_A、12); //将计时器设置为 fs=2ksps 加载值 //如果计时器加载值=5000;fs=1ksps // sysclock=20MHz,因此 TSYs=1/22000000sec;获得1ms 延迟 //我们需要加载1ms/0.5us 的计时器 TimerEnable (TIMER0_BASE、TIMER_A); // ADCSequenceDisable (ADC0_BASE、3); // ADCClockConfigSet (ADC0_BASE、ADC_CClock_SRC_PLL | ADC_CClock_RATE_FULL、266); ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_PROCESSOR、0); ADCSequenceConfigure (ADC1_base、3、ADC_TRIGGER_PROCESSOR, 0); ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceEnable (ADC0_BASE、3); ADCSequenceEnable (ADC1_BASE、3); ADCIntClear (ADC0_BASE、3); while (1) { ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END); ADCIntClear (ADC1_BASE、3); ADCProcessorTrigger (ADC1_base、3); //触发 ADC 转换。 while (!ADCIntStatus (ADC1_base、3、false)){} //等待转换完成。 ADCIntClear (ADC1_BASE、3); //清除 ADC 中断标志。 ADCSequenceDataGet (ADC1_base、3、adcbuffer); //读取 ADC 值。 时基= adcbuffer[0]; ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END); ADCIntClear (ADC1_BASE、3); ADCProcessorTrigger (ADC1_base、3); //触发 ADC 转换。 while (!ADCIntStatus (ADC1_base、3、false)){} //等待转换完成。 ADCIntClear (ADC1_BASE、3); //清除 ADC 中断标志。 ADCSequenceDataGet (ADC1_base、3、adcbuffer); //读取 ADC 值。 triglvl = adcbuffer[0]; ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END); ADCIntClear (ADC0_BASE、3); ADCProcessorTrigger (ADC0_BASE、3); //触发 ADC 转换。 while (!ADCIntStatus (ADC0_BASE、3、false)){} //等待转换完成。 ADCIntClear (ADC0_BASE、3); //清除 ADC 中断标志。 ADCSequenceDataGet (ADC0_BASE、3、adcbuffer); //读取 ADC 值。 xpos = adcbuffer[0]; 对于(i=0;i<=1000;i++) { ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); ADCIntClear (ADC0_BASE、3); ADCProcessorTrigger (ADC0_BASE、3); //触发 ADC 转换。 while (!ADCIntStatus (ADC0_BASE、3、false)){} //等待转换完成。 ADCIntClear (ADC0_BASE、3); //清除 ADC 中断标志。 ADCSequenceDataGet (ADC0_BASE、3、adcbuffer); //读取 ADC 值。 adcdata1[i]= adcbuffer[0]; res0=adcddata1[i]; // GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、RES0); ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END); ADCIntClear (ADC1_BASE、3); ADCProcessorTrigger (ADC1_base、3); //触发 ADC 转换。 while (!ADCIntStatus (ADC1_base、3、false)){} //等待转换完成。 ADCIntClear (ADC1_BASE、3); //清除 ADC 中断标志。 ADCSequenceDataGet (ADC1_base、3、adcbuffer); //读取 ADC 值。 adcddata2[i]= adcbuffer[0]; res1=adcddata2[i]; //GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_4、RES1); } }
。
谢谢主席先生。 我能够使用这两个 ADC 进行采样。 这是我的当前代码。 但是、我观察到采样信号中的失真、无法弄清原因。
您设置了计时器、但随后在循环中使用了"ADCProcessorTrigger()"、而未使用"ADC_TRIGGER_WAIT"。 对于同步转换的简单 CPU 触发、序列更像这样:
ADCProcessorTrigger (ADC0_BASE、3 | ADC_TRIGGER_WAIT);//设置触发器但等待。 ADCProcessorTrigger (ADC1_base、3); //触发两个 ADC while (!ADCIntStatus (ADC0_BASE、3、false)){} //等待转换完成。 ADCSequenceDataGet (ADC0_BASE、3、&adcddata1[i]); //读取 ADC 值。 while (!ADCIntStatus (ADC1_base、3、false)){} //等待转换完成。 ADCSequenceDataGet (ADC1_base、3、&adcdata2[i]); //读取 ADC 值。
主席先生、我在 for 循环中使用过这种方法、但存储了值
在 adcddata1和 adcddata2中、现在变为零。
我无法看到任何转换。
ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END); ADCIntClear (ADC0_BASE、3); ADCIntClear (ADC1_BASE、3); ADCProcessorTrigger (ADC0_BASE、3 | ADC_TRIGGER_WAIT);//设置触发器但等待。 ADCProcessorTrigger (ADC1_base、3); //触发两个 ADC while (!ADCIntStatus (ADC0_BASE、3、false)){} //等待转换完成。 ADCSequenceDataGet (ADC0_BASE、3、&adcddata1[i]); //读取 ADC 值。 adcdata1[i]= adcbuffer[0]; while (!ADCIntStatus (ADC1_base、3、false)){} //等待转换完成。 ADCSequenceDataGet (ADC1_base、3、&adcdata2[i]); //读取 ADC 值。 adcddata2[i]= adcbuffer[0];
实际上、您应该卡在 while 环路中等待 ADC0。 您需要将"ADC_TRIGGER_SIGNAL "添加到"ADCProcessorTrigger (ADC1_base、3);"语句。 我附加了一个示例.zip 项目、该项目对通道 AIN0和 AIN1进行5个同步转换。 使用 code composer "File""Import"函数将此项目添加到您的工作区。
/cfs-file/__key/communityserver-discussions-components-files/908/SimultaneousADC.zip