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:
前言:
先放电路连接图:
雨滴传感器是由两个模块组成,一个是用于检测雨水的防雨板,还一个是控制模块。
雨滴传感器可以用于汽车领域的自动控制雨刷器,还可以用于农业领域的感应是否下雨,还可以做家庭物联网中的自动化感知。
正文:
1.知识点:
analogSetWidth(bit);
设置模拟信号采样分辨率;
以上是关于ESP32使用I2S控制ADC和DAC的主要内容,如果未能解决你的问题,请参考以下文章
ESP32学习笔记(39)——播放MP3文件(内部DAC方式)