- 在 Arduino 环境下经常使用的 analogWrite(PIN, arg) 语法并不是真正的DAC模拟输出,也只是1kHZ的PWM 波模拟而成!
- 支持ADC功能的引脚请查看:引脚定义
- 本次ESP32输出DAC使用的是:esp32-hal-dac.c 和 esp32-hal-dac.h 这两个文件!
- 想使用ESP32的PWM功能请查看:《ESP32 学习笔记》 之Arduino环境下 如何优雅的输出频率可变的PWM波 这篇
- 查看 esp32-hal-dac.c 文件,我们很容易看出 DAC功能 仅适用于 IO25 和 IO26 两个引脚,并在dacWrite函数中进行了判断,其他的引脚一律跳出函数,这点非常重要哦~
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")));
- 接下来看下我写的例子吧!
/*
@功能:输出两路DAC,可用来输出音频
@时间:2020/3/5
@作者:刘泽文
@QQ:2822604962
*/
#include <Arduino.h>
#include <esp32-hal-dac.h>//DAC功能引用该库,可以不进行#include<>引用
//查看源码后得到,DAC引脚只能是这两个引脚
#define LED1 25
#define LED2 26
void setup(){
//长时候发现,DAC的IO口也可以不进行初始化
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
}
void loop()
{
// 逐渐变亮
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle = dutyCycle + 1)
{
dacWrite(LED1, dutyCycle); // 输出DAC
dacWrite(LED2, 255 - dutyCycle); // 输出DAC
delay(5);
}
// 逐渐变暗
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle = dutyCycle - 1)
{
dacWrite(LED1, dutyCycle); // 输出DAC
dacWrite(LED2, 255 - dutyCycle); // 输出DAC
delay(5);
}
}
- 实验结果:
IO25和IO26端口上的LED为呼吸灯闪烁,并且亮度互补。