ESP32外设-5.DAC入门
说明:
- 本文档由DuRuofu撰写,由DuRuofu负责解释及执行。
- 本文档介绍ESP32外设,数模转换器的使用。
修订历史:
文档名称 | 版本 | 作者 | 时间 | 备注 |
---|---|---|---|---|
ESP32外设-DAC入门 | v1.0.0 | DuRuofu | 2024-03-05 | 首次建立 |
ESP32外设-DAC入门
一、介绍
ESP32 有两个 8 位数模转换器 (DAC) 通道,分别连接到 GPIO25(通道 1)和 GPIO26(通道 2)。每个 DAC 通道可以将数字值 0 ~ 255 转换成模拟电压 0 ~ Vref(此处的 Vref 为 VDD3P3_RTC 引脚输入的参考电压,一般来说其输入的电压值应等于电源电压 VDD)。输出电压可按以下方式计算:
1 |
|
通道序号 | GPIO(ESP32) |
---|---|
DAC_CHANNEL_1 |
GPIO25 |
DAC_CHANNEL_2 |
GPIO26 |
头文件有:
dac.h
:原有 DAC 驱动的最上层头文件,只包含在使用原有驱动 API 的应用程序中。dac_oneshot.h
:新 DAC 驱动的最上层头文件,应包含在使用新驱动 API(单次模式)的应用程序中。dac_cosine.h
:新 DAC 驱动的最上层头文件,应包含在使用新驱动 API(余弦模式)的应用程序中。dac_continuous.h
:新 DAC 驱动的最上层头文件,应包含在使用新驱动 API(连续模式)的应用程序中。
原有驱动程序与新驱动程序无法共存。使用原有驱动需包含
dac.h
,使用新驱动需包含dac_oneshot.h
、dac_cosine.h
和dac_continuous.h
。后续更新或将移除原有驱动程序。
二、使用
ESP32 有两个 DAC 通道。通道的软件资源互相独立,用户可以根据具体情况调用 dac_oneshot_handle_t
、 dac_cosine_handle_t
或 dac_continuous_handle_t
来管理不同通道,但不支持在同一个通道上注册不同模式。
2.1 电压直接输出(单次/直接模式)
DAC 通道每次调用 dac_oneshot_output_voltage()
(可在 ISR 中调用)时都可以将一个 8 位数字转换为模拟值。直至下一次转换开始前,DAC 通道上都将维持该模拟电压。开始转换电压前,需要首先调用 dac_oneshot_new_channel()
来启用该 DAC 通道。
2.2 连续波输出(连续/DMA 模式)
DAC 通道可以通过 DMA 连续转换数字信号,这种模式下有三种写入 DAC 数据的方法:
- 常规写入(同步):一次性传输所有数据并在所有数据均已载入 DMA 缓冲区前保持阻塞状态。如果不再继续输入数据,电压将维持在最后的转换值。该模式通常用于传输音频等长信号。
- 循环写入:在数据载入 DMA 缓冲区后,缓冲区中的数据将以非阻塞的方式被循环转换。但要注意,输入的缓冲区大小受 DMA 描述符数量和 DMA 缓冲区大小的限制。该模式通常用于传输如正弦波等需要重复的短信号。为了启用循环写入,需要在启用 DAC 连续模式后调用
dac_continuous_write_cyclically()
。 - 异步写入。可根据事件回调异步传输数据。需要调用
dac_event_callbacks_t::on_convert_done
以启用异步模式。用户在回调中可得到dac_event_data_t
,其中包含 DMA 缓冲区的地址和长度,即允许用户直接将数据载入 DMA 缓冲区。启用异步写入前需要调用dac_continuous_register_event_callback()
、dac_event_callbacks_t::on_convert_done
和dac_continuous_start_async_writing()
。注意,异步写入一旦开始,回调函数将被持续触发。调用dac_continuous_write_asynchronously()
可以在某个单独任务中或直接在回调函数中载入数据。
2.3 余弦波输出(余弦模式)
DAC 外设中包含一个余弦波发生器,可以在通道上产生余弦波。用户可以通过struct dac_cosine_config_t
结构体配置余弦波的频率、振幅和相位。启用该模式需要先调用 dac_cosine_new_channel()
将 DAC 转换成余弦模式,然后调用 dac_cosine_start()
启动余弦波发生器。
目前,余弦波发生器仅有 RTC_FAST
一个时钟源,可通过选择 dac_cosine_clk_src_t::DAC_COSINE_CLK_SRC_RTC_FAST
来启用该时钟源。该时钟源为默认时钟源,与 dac_cosine_clk_src_t::DAC_COSINE_CLK_SRC_RTC_DEFAULT
相同。
struct dac_cosine_config_t
结构体用于配置DAC(数字到模拟转换器)的余弦波通道。以下是其成员变量的参数说明:
dac_channel_t chan_id
:余弦波通道ID,指定哪个DAC通道将产生余弦波。uint32_t freq_hz
:余弦波频率,单位为Hz。该频率由RTC_FAST时钟驱动,RTC_FAST时钟是从RC_FAST时钟分频得到的。默认RTC时钟下,余弦波最小频率约为130Hz。理论上虽然可以支持高达数MHz的频率,但由于硬件限制,在高频下波形会失真。通常不建议设置超过200kHz的频率。dac_cosine_clk_src_t clk_src
:余弦波生成器的时钟源,目前只支持DAC_COSINE_CLK_SRC_DEFAULT
。dac_cosine_atten_t atten
:余弦波幅度的衰减。dac_cosine_phase_t phase
:余弦波的相位,仅支持DAC_COSINE_PHASE_0
或DAC_COSINE_PHASE_180
,设置不支持的相位时,默认为0。int8_t offset
:余弦波的直流偏移量。bool force_set_freq
:强制设置余弦波频率。struct dac_cosine_config_t::[anonymous] flags
:余弦模式的标志位。
三、案例
3.1 电压直接输出(单次/直接模式)
1 |
|
效果:每500ms电压跳变一次
3.2 连续波输出(连续/DMA 模式)
1、常规写入(同步)
参考: peripherals/dac/dac_continuous/dac_audio
2、循环写入
参考: peripherals/dac/dac_continuous/signal_generator
3、异步写入
参考: peripherals/dac/dac_continuous/dac_audio
3.3 余弦波输出(余弦模式)
1 |
|
效果:
我们得到了两路余弦信号,其中一路还设置了180度的相位偏移和6dB的衰减。