ESP32使用DAC(Arduino)
目录
介绍
本文展示了在Arduino环境下ESP32的DAC的使用。
ESP32有2路8位DAC,其中DAC1在PIN25,DAC2在PIN26,DAC引脚由于是模拟引脚,因此无法通过IO_MUX映射。
Arduino库提供了 dacWrite(uint8_t pin, uint8_t value) 这个函数,只需要传入引脚号(25或26)以及8位的输出设定值即可。
ESP32还能通过I2S将数据连续输出到DAC,这在DAC播放音频时十分有用,这种方法详见我的另一篇文章:ESP32使用I2S及I2S输出到DAC(Arduino)
还有一些高级用法,需要IDF库,可参考ESP-IDF编程指南DAC章节
函数实现和简化
使用 dacWrite 函数是最方便的方法,但该函数封装得比较完备或者说复杂,因此速度可能会牺牲一些,此函数位于 esp32-hal-dac.c 中(路径在Arduino放开发板包的文件夹里的:\esp32\hardware\esp32\1.0.6\cores\esp32,其中1.0.6是版本,我这里的可能偏旧一点),函数实现如下:
void IRAM_ATTR __dacWrite(uint8_t pin, uint8_t value)
{
if(pin < 25 || pin > 26){
return;//not dac pin
}
pinMode(pin, ANALOG);
uint8_t channel = pin - 25;
//Disable Tone
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
if (channel) {
//Disable Channel Tone
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN2_M);
//Set the Dac value
SET_PERI_REG_BITS(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_DAC, value, RTC_IO_PDAC2_DAC_S); //dac_output
//Channel output enable
SET_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);
} else {
//Disable Channel Tone
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
//Set the Dac value
SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, value, RTC_IO_PDAC1_DAC_S); //dac_output
//Channel output enable
SET_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);
}
}
extern void dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite")));
可见该函数每次都要判断引脚号是否合法,然后设置引脚模式,还要清除一些东西,实际上这里的许多操作不需要每次都执行,据我自己测试,除了 SET_PERI_REG_BITS 函数,其他的在初始化时执行一次即可,所以代码可以改成以下的形式:
#define dac1Write(value) SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, (value), RTC_IO_PDAC1_DAC_S)
#define dac2Write(value) SET_PERI_REG_BITS(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_DAC, (value), RTC_IO_PDAC2_DAC_S)
void setup(){
dacWrite(25, 0);//利用该函数初始化DAC1(PIN25)
}
void loop(){
uint8_t test = 0;
while(1){//锯齿波测试代码
dac1Write(test++);//设置DAC1的值
}
}
也就是在初始化DAC时利用 dacWrite 函数来让它配置好,之后只需要使用代码里这两个宏来修改输出值就可以了。
据测试,直接使用 dacWrite 时锯齿波的频率约为 735Hz,改为 dac1Write 后频率提升至约 3380Hz,速度提升到了原来的约4.5倍。
作者:LightAndElectricity