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.
你(们)好
我当前使用1.5V 电池来测试 F28379D EVM 板的 ADC 误差、但下图显示了电流测试结果。 ADC 的最大值和最小值均超过数据表中写入的 ADC 误差7 LSB。 如何将其设置为实现 ADC 误差7 LSB?
我首先编写的以下程序丢弃 ADC 值的前9000个数据、并在 ADC 模块稳定后计算3000个 ADC 值的最大和最小值以及平均 ADC 值。
//############################################################################# // // FILE: adc_ex2_soc_epwm.c // // TITLE: ADC ePWM Triggering // //! \addtogroup driver_example_list //! <h1>ADC ePWM Triggering</h1> //! //! This example sets up ePWM1 to periodically trigger a conversion on ADCA. //! //! \b External \b Connections \n //! - A0 should be connected to a signal to convert //! //! \b Watch \b Variables \n //! - \b adcAResults - A sequence of analog-to-digital conversion samples from //! pin A0. The time between samples is determined based on the period //! of the ePWM timer. //! // //############################################################################# // // $Release Date: $ // $Copyright: // Copyright (C) 2013-2022 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // // Included Files // #include "driverlib.h" #include "device.h" // // Defines // #define RESULTS_BUFFER_SIZE 3000 #define EX_ADC_RESOLUTION 12 // 12 for 12-bit conversion resolution, which supports (ADC_MODE_SINGLE_ENDED) // Sample on single pin (VREFLO is the low reference) // Or 16 for 16-bit conversion resolution, which supports (ADC_MODE_DIFFERENTIAL) // Sample on pair of pins (difference between pins is converted, subject to // common mode voltage requirements; see the device data manual) // // Globals // volatile uint16_t adcAResults[RESULTS_BUFFER_SIZE]; // Buffer for results uint16_t index; // Index into result buffer uint16_t i; volatile uint32_t sum_of_adc_data; volatile uint32_t avg_adc_value, diff_value; volatile uint16_t bufferFull; // Flag to indicate buffer is full volatile uint32_t Max_adc_value = 0x00000000; volatile uint32_t Min_adc_value = 0xFFFFFFFF; // // Function Prototypes // void initADC(void); void initEPWM(void); void initADCSOC(void); __interrupt void adcA1ISR(void); // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pullups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_ADCA1, &adcA1ISR); // // Set up the ADC and the ePWM and initialize the SOC // initADC(); initEPWM(); initADCSOC(); // // Initialize results buffer // for(index = 0; index < RESULTS_BUFFER_SIZE; index++) { adcAResults[index] = 0; } index = 0; bufferFull = 0; // // Enable ADC interrupt // Interrupt_enable(INT_ADCA1); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; // // Loop indefinitely // while(1) { // // Start ePWM1, enabling SOCA and putting the counter in up-count mode // EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A); EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP); // // Wait while ePWM1 causes ADC conversions which then cause interrupts. // When the results buffer is filled, the bufferFull flag will be set. // if(bufferFull == 3){ EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A); EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE); for(i = 0; i < RESULTS_BUFFER_SIZE; i++){ if(adcAResults[i] > Max_adc_value){ Max_adc_value = adcAResults[i]; } if(adcAResults[i] < Min_adc_value){ Min_adc_value = adcAResults[i]; } sum_of_adc_data += adcAResults[i]; } avg_adc_value = sum_of_adc_data / RESULTS_BUFFER_SIZE; diff_value = 2121 - avg_adc_value; ESTOP0; } // while(bufferFull == 0) // { // } // bufferFull = 0; // Clear the buffer full flag // // // // // Stop ePWM1, disabling SOCA and freezing the counter // // // EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A); // EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE); // // Software breakpoint. At this point, conversion results are stored in // adcAResults. // // Hit run again to get updated conversions. // //ESTOP0; } } // // Function to configure and power up ADCA. // void initADC(void) { // // Set ADCDLK divider to /4 // ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_2_0); // // Set resolution and signal mode (see #defines above) and load // corresponding trims. // #if(EX_ADC_RESOLUTION == 12) ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); #elif(EX_ADC_RESOLUTION == 16) ADC_setMode(ADCA_BASE, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL); #endif // // Set pulse positions to late // ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV); // // Power up the ADC and then delay for 1 ms // ADC_enableConverter(ADCA_BASE); DEVICE_DELAY_US(1000); } // // Function to configure ePWM1 to generate the SOC. // void initEPWM(void) { // // Disable SOCA // EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A); // // Configure the SOC to occur on the first up-count event // EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA); EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1); // // Set the compare A value to 1000 and the period to 1999 // Assuming ePWM clock is 100MHz, this would give 50kHz sampling // 50MHz ePWM clock would give 25kHz sampling, etc. // The sample rate can also be modulated by changing the ePWM period // directly (ensure that the compare A value is less than the period). // EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000); EPWM_setTimeBasePeriod(EPWM1_BASE, 1999); // // Set the local ePWM module clock divider to /1 // EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // // Freeze the counter // // EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE); } // // Function to configure ADCA's SOC0 to be triggered by ePWM1. // void initADCSOC(void) { // // Configure SOC0 of ADCA to convert pin A0. The EPWM1SOCA signal will be // the trigger. // - For 12-bit resolution, a sampling window of 15 (75 ns at a 200MHz // SYSCLK rate) will be used. For 16-bit resolution, a sampling window // of 64 (320 ns at a 200MHz SYSCLK rate) will be used. // - NOTE: A longer sampling window will be required if the ADC driving // source is less than ideal (an ideal source would be a high bandwidth // op-amp with a small series resistance). See TI application report // SPRACT6 for guidance on ADC driver design. // #if(EX_ADC_RESOLUTION == 12) ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN0, 128); #elif(EX_ADC_RESOLUTION == 16) ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN0, 64); #endif // // Set SOC0 to set the interrupt 1 flag. Enable the interrupt and make // sure its flag is cleared. // ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); } // // ADC A Interrupt 1 ISR // __interrupt void adcA1ISR(void) { // // Add the latest result to the buffer // adcAResults[index++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0); // // Set the bufferFull flag if the buffer is full // if(RESULTS_BUFFER_SIZE <= index) { index = 0; bufferFull += 1; } // // Clear the interrupt flag // ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); // // Check if overflow has occurred // if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1)) { ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1); ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); } // // Acknowledge the interrupt // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); }
您好 Poyi、
您对 ADC 使用的采样率是多少(以每秒样本数为单位)? 此外、您是否有某种可以过滤 ADC 输入引脚噪声的电容器?
此致、
Omer Amir
你(们)好
SYSCLK = 120MHz (8.33ns)
ADCCLK = 60MHz (16.6ns)
ADC 采样窗口= 128
DACB 输出2048 (1.5V)
我做了另一个实验、使用 DACB 输出2048 (1.5V)连接到 ADCA0、向 ADC 128 SampleWindow 和 ADC 输入添加0.1uF 电容器来滤除噪声、但仍有很多噪声、如下图所示。
您好 Poyi、
测量1.5V 电池时的原始设置是什么? 听起来输入端没有电容器、还有什么不同吗? 接下来、验证电池连接是否非常牢固、 任何松动的连接都可能产生噪音。
作为一个附带问题、您是使用 SysConfig 配置 任何初始化、还是您配置了随附的代码?
此致、
Omer Amir
你(们)好
您好、Poyi、
Omer 因感恩节假期而不在办公室。 他将于下周返职、请在周一/周二回复。 对拖延表示真诚的道歉。
此致、Santosh
您好 Poyi、
我将对此进行更多研究、并尝试对该器件的降噪进行更多研究。 明天我将尝试在一天结束前得到答复。
此致、
Omer Amir
您好 Poyi、
有关设置的一些后续问题:
此致、
Omer Amir
您好!
以上是我问题的答案、如果您有相同的 EVM 硼、您能帮我测试 ADC 示例吗?谢谢。
此致、
李先生
您好 Poyi、
选择任何 ADC 通道时是否会发生错误? 如果是这样、当您选择另一个 ADC 时是否仍然发生? 我将研究您可能会看到 A0上有噪声的原因、但现在您可以尝试类似 A5的方法来查看问题是否一致。
此致、
Omer Amir