概述
ESP32 具有两个8位数模转换器通道(DAC),其中 GPIO25 为通道1 、GPIO26为通道2。
DAC驱动器允许将这些通道设置为任意电压。
当使用“内置DAC模式”时,还可以通过I2S驱动器以DMA风格的写入采样数据来驱动DAC通道。
有关其他模拟输出选项,请参见Sigma-delta调制模块和LED控制模块。这两个模块均产生高频PWM输出,可以对其进行硬件低通滤波,以生成低频任意电压模拟输出。
Arduino层编程
极为简单,就只需调用一个函数:void dacWrite(uint8_t pin, uint8_t value) 即可。
其中 pin 只能为 25 与 26 号引脚。由于是8位转换器,所以可知value的范围:0-255。
而底层则是直接调用寄存器,可以提高程序的执行效率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void IRAM_ATTR __dacWrite(uint8_t pin, uint8_t value) { if(pin < 25 || pin > 26) { return; } pinMode(pin, ANALOG); uint8_t channel = pin - 25;
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN); if (channel) { CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN2_M); SET_PERI_REG_BITS(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_DAC, value, RTC_IO_PDAC2_DAC_S); SET_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE); } else { CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M); SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, value, RTC_IO_PDAC1_DAC_S); SET_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE); } }
|
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <Arduino.h>
uint8_t val = 0;
void setup() { Serial.begin(9600); dacWrite(25,0); delay(500); }
void loop() { delay(1000); val+=20; if(val>200) val=0; dacWrite(25,val); }
|
再来一个呼吸灯例程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <Arduino.h> #include <esp32-hal-dac.h>
#define LED1 25 #define LED2 26 void setup(){ pinMode(LED1,OUTPUT); pinMode(LED2,OUTPUT); } void loop() { for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle = dutyCycle + 1) { dacWrite(LED1, dutyCycle); dacWrite(LED2, 255 - dutyCycle); delay(5); } for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle = dutyCycle - 1) { dacWrite(LED1, dutyCycle); dacWrite(LED2, 255 - dutyCycle); delay(5); } }
|
后续
接下来我会使用这两个DAC结合外围电路实现恒压源和恒流源,敬请期待
Gitalk 加载中 ...