ESP32 DAC->ADC 线性度堪忧

/ 2评 / 4

使用的测试案例如下:

/* ADC2 Example



   This example code is in the Public Domain (or CC0 licensed, at your option.)



   Unless required by applicable law or agreed to in writing, this

   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR

   CONDITIONS OF ANY KIND, either express or implied.

*/

#include <stdio.h>

#include <stdlib.h>

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"

#include "freertos/queue.h"

#include "driver/gpio.h"

#include "driver/adc.h"

#include "driver/dac.h"

#include "esp_system.h"

#include "esp_adc_cal.h"



#define DAC_EXAMPLE_CHANNEL     CONFIG_DAC_EXAMPLE_CHANNEL

#define ADC2_EXAMPLE_CHANNEL    CONFIG_ADC2_EXAMPLE_CHANNEL



void app_main(void)

{

    uint8_t output_data=0;

    int     read_raw;

    esp_err_t r;



    gpio_num_t adc_gpio_num, dac_gpio_num;



    r = adc2_pad_get_io_num( ADC2_EXAMPLE_CHANNEL, &adc_gpio_num );

    assert( r == ESP_OK );

    r = dac_pad_get_io_num( DAC_EXAMPLE_CHANNEL, &dac_gpio_num );

    assert( r == ESP_OK );



    printf("ADC channel %d @ GPIO %d, DAC channel %d @ GPIO %d.
", ADC2_EXAMPLE_CHANNEL, adc_gpio_num,

                DAC_EXAMPLE_CHANNEL, dac_gpio_num );



    dac_output_enable( DAC_EXAMPLE_CHANNEL );



    //be sure to do the init before using adc2. 

    printf("adc2_init...
");

    adc2_config_channel_atten( ADC2_EXAMPLE_CHANNEL, ADC_ATTEN_11db );



    vTaskDelay(2 * portTICK_PERIOD_MS);



    printf("start conversion.
");

    while(1) {

        dac_output_voltage( DAC_EXAMPLE_CHANNEL, output_data++ );

        r = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, ADC_WIDTH_12Bit, &read_raw);

        if ( r == ESP_OK ) {

            printf("%d: %d
", output_data, read_raw );

        } else if ( r == ESP_ERR_INVALID_STATE ) {

            printf("%s: ADC2 not initialized yet.
", esp_err_to_name(r));

        } else if ( r == ESP_ERR_TIMEOUT ) {

            //This can not happen in this example. But if WiFi is in use, such error code could be returned.

            printf("%s: ADC2 is in use by Wi-Fi.
", esp_err_to_name(r));

        } else {

            printf("%s
", esp_err_to_name(r));

        }



        vTaskDelay( 2 * portTICK_PERIOD_MS );

    }

}

把ADC的输入增益调整为11db,以便可以全量程测量.做出数据后生成图表.

其中,DAC范围是0~254,ADC范围是0~4095.

可见整体斜率是有肉眼可见变化,导出ADC数值/DAC数值比例的图.如下.

可见要不就是ADC的线性度不好,要不就是DAC的线性度不好,为了排除问题,这两个PIN是直接短接,并没有用杜邦线等外界干扰.

ADC/DAC在中间范围可信度最高.但是总体来说是越往后,采样到的比实际数值更高,或者说,DAC生成的更高.

所有实验数据.

  1. ??说道:

    是不是采样时间非线性导致的

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注