ESP32使用I2S控制ADC和DAC

Posted milk_docker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP32使用I2S控制ADC和DAC相关的知识,希望对你有一定的参考价值。

一、创建示例项目

        板子用的是ESP-WROOM-32,IDE是VScode+ESP-IDF。

        最近自己一个项目要用ESP32的ADC采样音频。看了一堆相关的介绍和例程,要么是没讲清楚,要么是移植了有问题。突然发现有官方的例程,改一下就可以直接用了。

        首先 ctrl+shift+p 打开命令面板,键入 ESP-IDF show examples projects :

 打开ESP-IDF example界面,找到i2s_adc_dac例程:

 点击 使用例程i2s_adc_dac创建项目就可以了。

        该示例使用I2S控制ADC采样以及控制DAC数据流输出;程序首先会使用ADC采样音频,接着通过DAC回放录制的音频,最后播放项目中的音频文件,不断循环。

二、相关函数

        部分I2S ADC相关函数

/**
 * @brief 启用I2S作为ADC模式
 * @note 该函数将锁定ADC,以防止数据在ADC采样时损坏
 *
 * @param i2s_num I2S端口值,0或1
 * @return
 *     - ESP_OK                成功
 *     - ESP_ERR_INVALID_ARG   参数错误
 *     - ESP_ERR_INVALID_STATE 驱动状态错误
 */
esp_err_t i2s_adc_enable(i2s_port_t i2s_num);

/**
 * @brief 停止I2S的ADC模式
 * @param i2s_num i2s端口值,0或1
 * @note 函数会释放ADC,这样其他任务就能使用ADC
 * @return
 *     - ESP_OK                 成功
 *     - ESP_ERR_INVALID_ARG    参数错误
 *     - ESP_ERR_INVALID_STATE  驱动状态错误
 */
esp_err_t i2s_adc_disable(i2s_port_t i2s_num);

/**
 * @brief 将数据从I2S DMA接收缓存器读取到内存
 *
 * @param i2s_num         I2S端口值:I2S_NUM_0, I2S_NUM_1
 *
 * @param dest            数据存入地址
 *
 * @param size            需要读取的字节数
 *
 * @param[out] bytes_read 读取到的字节数,如果超时,读取到的字节数会少于所需的大小
 *
 * @param ticks_to_wait   RX缓存器等待超时的RTOS时钟。如果经过这么多个时钟周期后,DMA接收缓存器中仍无可用的数据,函数将会返回。
 * (注意如果分段从DMA缓存器中读取数据,总的操作仍有可能超时)填入portMAX_DELAY将不会引发超时。
 *
 * @note 如果启用了内置ADC模式,则应在整个读取过程中调用i2s_adc_enable和i2s_adc_disable,以防数据被破坏
 *
 * @return
 *     - ESP_OK               成功
 *     - ESP_ERR_INVALID_ARG  参数错误
 */
esp_err_t i2s_read(i2s_port_t i2s_num, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait);

 每一次采样过程最少只需要以上3个函数即可。

简单的ADC采样+串口输出的代码如下:

//i2s number 
#define EXAMPLE_I2S_NUM           (0)
//I2S read buffer length I2S读取缓存器大小
#define EXAMPLE_I2S_READ_LEN      (1024*2)

esp_err_t app_main(void)

    int i2s_read_len = EXAMPLE_I2S_READ_LEN;
    size_t bytes_read;
    //系统对数组大小有限制,使用calloc则不会有相关问题
    char* i2s_read_buff = (char*) calloc(i2s_read_len, sizeof(char));
    //初始化I2S
    example_i2s_init();
    esp_log_level_set("I2S", ESP_LOG_INFO);
    
    while(1)
        //启动I2S ADC采样
        i2s_adc_enable(EXAMPLE_I2S_NUM);
        //从ADC读取数据存放在内存中
        i2s_read(EXAMPLE_I2S_NUM, (void*) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY);
        //串口输出读取到的数据
        example_disp_buf((uint8_t*) i2s_read_buff, i2s_read_len);
        //禁用I2S ADC
        i2s_adc_disable(EXAMPLE_I2S_NUM);
        //延时1000ms
        vTaskDelay(1000 / portTICK_RATE_MS);
    
    //释放存储ADC采样数据的空间
    free(i2s_read_buff);
    i2s_read_buff = NULL;
    
    return ESP_OK;

        ESP32的ADC最高精度为12位,I2S精度为16位,所以虽然数据缓存区的数据类型为char,每个数据仍然占用了两个字节。存储方式为第一个字节存储数据的低八位,第二个字节的低四位存储数据的高四位,第二个字节的高四位为无效信息。

ESP3211.雨滴探测实验(ADC)

上一篇:

【ESP32】10.PCF8591数模转换器实验(IIC总线/wire库)

之前更新过DAC,这篇文章是对应的ADC:

【ESP32】3.双色LED实验(DAC)

前言:

先放电路连接图:

雨滴传感器是由两个模块组成,一个是用于检测雨水的防雨板,还一个是控制模块。

雨滴传感器可以用于汽车领域的自动控制雨刷器,还可以用于农业领域的感应是否下雨,还可以做家庭物联网中的自动化感知。 

正文:

1.知识点:

analogSetWidth(bit);

设置模拟信号采样分辨率;

以上是关于ESP32使用I2S控制ADC和DAC的主要内容,如果未能解决你的问题,请参考以下文章

ESP32学习笔记(39)——播放MP3文件(内部DAC方式)

ESP32 单片机学习笔记 - 04 - ADC和定时器

ESP32音视频传输①用I2S通过内部DAC或MAX98357A播放音乐/录音数据及接受网络广播

ESP32 DAC

ESP3211.雨滴探测实验(ADC)

ESP3211.雨滴探测实验(ADC)