《ESP32 学习笔记》 之Arduino环境下 使用DAC模拟输出(是真的DAC哦!)完成两路呼吸灯

  • 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为呼吸灯闪烁,并且亮度互补。

发布了16 篇原创文章 · 获赞 18 · 访问量 4021

猜你喜欢

转载自blog.csdn.net/qq_41868901/article/details/104690524