本文章 来自原创专栏《ESP32教学专栏 (基于ESP-IDF)》,讲解如何使用 ESP-IDF 构建 ESP32 程序,发布文章并会持续为已发布文章添加新内容! 每篇文章都经过了精打细磨!
↓↓↓通过下方对话框进入专栏目录页↓↓↓
CSDN 请求进入目录 _ O x
是否进入ESP32教学导航(基于ESP-IDF)?
确定
文章目录
一、ESP32 DAC 概览
ESP32有两个8位DAC(数字到模拟转换器)通道,连接GPIO25(通道1)和GPIO26(通道2)。
同时,当使用内置DAC模式( built-in DAC mode
)时,通过I2S驱动器,DAC通道也可以由“数字控制器”利用“写入的DMA风格示例数据”进行驱动。
不知道转述的准不准确😂,乐鑫官网的原话是:
The DAC channels can also be driven with DMA-style written sample data by the digital controller, via the I2S driver when using the “built-in DAC mode”.
注意:
本文 不介绍 通过I2S
来驱动DAC
通道序号 | ★GPIO(ESP32) | GPIO(ESP32-S2) |
---|---|---|
DAC_CHANNEL_1 | GPIO25 | GPIO17 |
DAC_CHANNEL_2 | GPIO26 | GPIO18 |
二、DAC的使用① —— 在通道GPIO上输出指定电压
在通道GPIO上输出指定电压是DAC最基本的使用,方法很简单。
官方在此功能上只提供了4个API函数:
dac_output_voltage()
设置某DAC通道的输出电压 (关键)dac_output_enable()
启动DAC输出dac_output_disable()
关闭DAC输出dac_pad_get_io_num()
【非必须】 用于通过DAC通道编号获取对应的GPIO编号
1、API 函数简介
函数1 | dac_output_voltage() |
---|---|
函数原型 | esp_err_t dac_output_voltage(dac_channel_t channel, uint8_t dac_value) |
简介 | 设置 DAC 输出电压。由于 DAC 输出为8位.所以取值为0-255 正比对应于电源电压(如0 - 3.3V ) |
返回值 | 若成功则返回ESP_OK |
参数 | channel : DAC通道dac_value : DAC 欲输出值 |
函数2 | dac_output_enable() |
---|---|
函数原型 | esp_err_t dac_output_enable(dac_channel_t channel) |
简介 | 启动(使能)DAC 输出。 如果使用I2S驱动,则 左声道 对应 DAC 通道2,右声道 对应 DAC 通道1 |
返回值 | 若成功则返回ESP_OK |
参数 | channel : DAC 通道 |
函数3 | dac_output_disable() |
---|---|
函数原型 | esp_err_t dac_output_disable(dac_channel_t channel) |
简介 | 关闭DAC输出 |
返回值 | 若成功则返回ESP_OK |
参数 | channel : DAC通道 |
函数4 | dac_pad_get_io_num() |
---|---|
函数原型 | esp_err_t dac_pad_get_io_num(dac_channel_t channel, gpio_num_t * gpio_num) |
简介 | 获取特定DAC通道的GPIO号。 |
返回值 | 若成功则返回ESP_OK |
参数 | channel : 通道gpio_num : 用于接受获取到的GPIO编号的变量指针 |
2、示例
在3.3v供电,不进入睡眠状态的ESP32上,输出一个2V的电压
以下例程基于C++
#include <iostream>
#include "driver/dac.h"
extern "C" void app_main(void) {
/*DAC channel 1 is GPIO25*/
dac_output_voltage(DAC_CHANNEL_1, 155);
dac_output_enable(DAC_CHANNEL_1);
}
本示例的关键是:第8行函数dac_output_voltage(DAC_CHANNEL_1, 155);
的第二个参数 “155
”。它决定了输出电压是2V。
原因:
参考上文此函数简介“由于DAC输出为8位.所以取值为0-255
正比
对应于电源电压(如0 - 3.3V
)”。即:
V
o
u
t
=
N
255
V
d
d
V_{out} = \frac{N}{255} V_{dd}
Vout=255NVdd
其中,
N
N
N为dac_value
的值,
V
d
d
V_{dd}
Vdd 为电源电压(通常为3.3V)。计算得的
V
o
u
t
V_{out}
Vout 为输出的DAC电压。
当
N
=
155
N=155
N=155 时,有
V
o
u
t
=
155
255
V
d
d
=
155
255
×
3.3
V
≈
2.00588
V
V_{out} = \frac{155}{255} V_{dd} = \frac{155}{255}\times 3.3 \rm \ V \approx 2.00588\rm \ V
Vout=255155Vdd=255155×3.3 V≈2.00588 V
三、DAC 的使用② —— 在通道GPIO上输出正弦波
想要 DAC 输出正弦波/余弦波,ESP32 的 DAC 模块提供了 余弦波发生器Cosine Wave Generator
,并为开发者提供了 3 个API函数控制余弦波发生器。
1、API 函数简介
函数1 | dac_cw_generator_config() |
---|---|
函数原型 | esp_err_t dac_cw_generator_config(dac_cw_config_t *cw) |
简介 | 通过一个结构体来 配置DAC模块中的余弦波发生器功能。 |
返回值 | ESP_OK ——成功ESP_ERR_INVALID_ARG ——The parameter is NULL.参数为空 |
参数 | cw ——DAC 余弦函数发生器参数配置结构体指针 |
函数2 | dac_cw_generator_enable() |
---|---|
函数原型 | esp_err_t dac_cw_generator_enable() |
简介 | 打开余弦函数发生器 |
返回值 | ESP_OK ——成功 |
参数 | 无 |
函数3 | dac_cw_generator_disable() |
---|---|
函数原型 | esp_err_t dac_cw_generator_disable() |
简介 | 关闭余弦函数发生器 |
返回值 | ESP_OK ——成功 |
参数 | 无 |
2、余弦函数发生器参数配置结构体struct dac_cw_config_t
简介
struct dac_cw_config_t
配置DAC模块中的余弦波产生函数。
[dac_channel_t] en_ch
开启DAC通道的余弦波发生器。[dac_cw_scale_t] scale
设置余弦波发生器输出的振幅。[dac_cw_phase_t] phase
设置余弦波发生器输出的相位。[uint32_t] freq
设置余弦波发生器输出频率。范围:130(130Hz) ~ 55000(100KHz)。[int8_t] offset
设置余弦波发生器输出直流分量的电压值。注意:不合理的设置会导致波形过饱和。取值范围:-128 ∼ \sim ∼ 127。
3、部分枚举值解析
1、“振幅”:
/* DAC输出的振幅倍数,0x0表示默认(振幅为电源电压) */
enum dac_cw_scale_t {
DAC_CW_SCALE_1 = 0x0, // 1/1. 默认
DAC_CW_SCALE_2 = 0x1, // 1/2
DAC_CW_SCALE_4 = 0x2, // 1/4
DAC_CW_SCALE_8 = 0x3, // 1/8
}
2、“相位:”
/*余弦波发生器输出的相位。 */
enum dac_cw_phase_t {
DAC_CW_PHASE_0 = 0x2,// 相移+ 0°
DAC_CW_PHASE_180 = 0x3,// 相移+ 180°
}
4、示例
在 DAC通道1(在 ESP32 上对应GPIO25
)上,输出一个余弦波
#include <stdio.h>
#include "driver/dac.h"
void app_main(void) {
dac_cw_config_t config = {
.en_ch = DAC_CHANNEL_1,
.freq = 10000,
.scale = DAC_CW_SCALE_1,
.phase = DAC_CW_PHASE_0,
};
dac_cw_generator_config(&config);
// 打开余弦波发生器
dac_cw_generator_enable();
// 别忘了启动输出
dac_output_enable(DAC_CHANNEL_1);
}