【ESP32 C语言】ESP32与ESP32-S2使用adc_dma_read心得

前段时间因为课题需要,需要使用ESP32系列的MCU,刚拿到手,对很多东西都不懂,焦头烂额。经过一段时间,对ESP32已经有了一些了解,为了同学们不出现和我一样的情况,特在此写下一些经验分享。这篇文章是我对ESP32内部ADC的一些经验,希望对后来学习的同学们有帮助。

1.首先考虑需求

使用ESP32的ADC肯定是为了满足自己的设计需求,下面我将我使用过的ESP32与ESP32-S2两款ADC的一些经验写到下面:

1.1 ESP32与ESP32-S2的采样率

ESP32采样率最高到2MSPS(官方说法,但本人使用IDF V4.4.2亲测只能到250KSPS,若我输入500Ksps,得到的结果相邻两个是相同的,等同于250Ksps),除了ESP32能到这么高,ESP32其他系列如S2,S3,C3。最高仅支持83333Hz。且多通道打开后共享采样率,就是说官方的2MSPS与83333SPS都是最大采样率,开几个通道就是几个通道平分。

因此,如果你的课题对采样率有要求,建议慎重选择ESP32的ADC。我的课题就需要很高采样率,在学习了ESP32的ADC之后,不得不选择其他adc采样方案,希望大家不要走我的弯路,特此写下这篇经验分享。(对于想用ESP32外接SPI接口的高速ADC的同学,需慎重,ESP32的SPI有小坑,导致无法达到高速采样,SPI的主机发送无论是轮询还是中断,都具有较高延时,亲测轮询发送每个发送函数之间存在10us以上延时,中断发送存在20us左右延时,意味着主机CS的拉高拉低总会存在10us以上的延时。若我打算进行100ksps的采样,需要设置定时器每10us在中断函数中进行SPI的发送读取,可发送读取的间隔都在10us以上,我上一个任务的任务都没发完,下一个中断又来了。过不了多久ESP32就会重启。)

1.2 ESP32与ESP32-S2的ADC精度

ESP32的ADC精度真的很差!很差!很差!

【ESP32 C语言】ESP32与ESP32-S2使用adc_dma_read心得_第1张图片

 【ESP32 C语言】ESP32与ESP32-S2使用adc_dma_read心得_第2张图片

第一张图是乐鑫官网对ESP32内部噪声的一个测试图,第二张是我用ESP32采样5khz正弦波的图形。可以看出,其内部具有很大噪声,我的建议是,要用ESP32系列的ADC,一定不要选择ESP32...可以看看S2什么的。

下图是ESP32-S2采样5khz正弦波的时域图与频域图:

【ESP32 C语言】ESP32与ESP32-S2使用adc_dma_read心得_第3张图片

 【ESP32 C语言】ESP32与ESP32-S2使用adc_dma_read心得_第4张图片

可以看出比起ESP32,ESP32-S2在噪声控制方面有所改善。但采样率之前也说过只有最大83khz,需要使用的同学要注意。

2.代码踩坑经验

adc代码,我这里使用的是官方idf版本v4.4.2中dma_read例程。

本来想把adc的例程讲一遍的,但自己还有课题任务,就只分享自己的adc踩坑经验吧,希望之后的同学们不要踩坑。代码讲起来确实比较费时,有需要的同学们可以去B站搜索“ESP32 ADC”,有几个视频都很不错。

dma_read中的频率对ESP32并不准确

    adc_digi_configuration_t dig_cfg = {
        .conv_limit_en = ADC_CONV_LIMIT_EN,
        .conv_limit_num = 250,
        .sample_freq_hz = 10 * 1000,    
        .conv_mode = ADC_CONV_MODE,
        .format = ADC_OUTPUT_TYPE,
    };

该结构体中  .sample_freq_hz并不能使ESP32得到对应的采样率(对了,对于采样率,只改这个参数就可以了)。GITHUB上对这个问题有讨论:https://github.com/espressif/esp-idf/issues/8874

当然乐鑫也给出了解决办法, https://github.com/espressif/esp-idf/commit/cb62457f6dcb3077b38a74cfaffe19f5f23e4a00

更改相应的函数就可以实现准确的采样了,不知道后面的IDF对这个问题有没有修复 。ESP32-S2不受影响,不需更改。

总结

  1. ESP32与ESP32-S2的采样率分别为2MSPS(IDF实测250K)与83KSPS
  2. ESP32adc内部具有很大噪声,精度极差
  3. 使用官方API,ESP32不能获得实际的采样率,需更改函数才可以使用,上面已给出解决办法。

这是我第一次发经验分享,本来想写得比较详细,可写了之后才发现比较费时间,我还有课题要做,所以只能分享几个自己在ADC上踩的坑。对于ESP32的ADC还有什么疑问也可以评论,我看到就会解答。

最后,想用好ESP32的C语言编程,一定要学习freertos,B站的Michael老师讲的非常好,在这推荐一波:ESP32_freeRTOS教程一: 入门介绍_哔哩哔哩_bilibili

你可能感兴趣的:(ESP32,单片机,c语言,visual,studio,code)