Arduino编译ESP32使用AnalogWrite()函数报错

问题描述

今天使用Arduino对ESP32操作,刚编译的时候就报了如下所示的错误:
在这里插入图片描述
按照上面看来,说AnalogWrite这个函数没有定义,一时间感到纳闷,AnalogWrite这个函数不是内置的操作函数吗,检查拼写无误后,发现确实这个函数不存在,寻找不到源头。

问题解决

https://www.jianshu.com/p/7cef8e7b22d1

在百度上找到这位博主的文章,简洁明了,AnalogWrite这个函数对于ESP32的库还没有写,所以不能使用,但是官方给出了对应的替代方案如下所示:

统一说明一下,建议采用第二种方法,第一种方法我用示波器来看波形,发现PWM波相当的紊乱,第二种方法不会有这个现象,如果有朋友发现我的错误的话,可以在评论区一起讨论,万分感谢。

SigmaDelta()函数
LEDC()函数

下面分别是这位博主所说的两个函数应用实例:
①SigmaDelta()

int pwm_channel0 = 0;
int pwm_freq = 5000;
int pwm_value = 0;    //0-255
int i = 0;
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  // pinMode(LED_BUILTIN, OUTPUT);
  sigmaDeltaSetup(pwm_channel0, pwm_freq);
  sigmaDeltaAttachPin(LED_BUILTIN, pwm_channel0);
  sigmaDeltaWrite(pwm_channel0, pwm_value);
  Serial.begin(115200);
}

// the loop function runs over and over again forever
void loop() {
  for(i = 0; i < 255; i++){
    sigmaDeltaWrite(pwm_channel0, i);
    delay(10);
  }
  for(i = 255; i > 0; i--){
    sigmaDeltaWrite(pwm_channel0, i);
    delay(10);
  }
}

这边简单的对几个主要函数进行介绍(贴上库文件中的函数体内容)

//sigmaDeltaSetup函数,初始化通道和频率,可见一共可以设置8个通道,还给出了频率范围
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500
{
    if(channel > 7) {
        return 0;
    }
#if !CONFIG_DISABLE_HAL_LOCKS
    static bool tHasStarted = false;
    if(!tHasStarted) {
        tHasStarted = true;
        _sd_sys_lock = xSemaphoreCreateMutex();
    }
#endif
    uint32_t apb_freq = getApbFrequency();
    uint32_t prescale = (apb_freq/(freq*256)) - 1;
    if(prescale > 0xFF) {
        prescale = 0xFF;
    }
    SD_MUTEX_LOCK();
    SIGMADELTA.channel[channel].prescale = prescale;
    SIGMADELTA.cg.clk_en = 0;
    SIGMADELTA.cg.clk_en = 1;
    SD_MUTEX_UNLOCK();
    uint32_t iarg = channel;
    addApbChangeCallback((void*)iarg, _on_apb_change);
    return apb_freq/((prescale + 1) * 256);
}


//引脚映射函数,可以将需要的引脚对应到通道上,比如说我们使用IO2,通道0,就填sigmaDeltaAttachPin(LED_BUILTIN, pwm_channel0);即可
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel) //channel 0-7
{
    if(channel > 7) {
        return;
    }
    pinMode(pin, OUTPUT);
    pinMatrixOutAttach(pin, GPIO_SD0_OUT_IDX + channel, false, false);
}


//PWM值写入函数,只有八位
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit
{
    if(channel > 7) {
        return;
    }
    duty -= 128;
    SD_MUTEX_LOCK();
    SIGMADELTA.channel[channel].duty = duty;
    SD_MUTEX_UNLOCK();
}

②LEDC()

int pwm_channel0 = 0;
int pwm_freq = 5000;
int pwm_value = 10;    //0-255
int i = 0;
int add_value = 3;
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  // pinMode(LED_BUILTIN, OUTPUT);
  // sigmaDeltaSetup(pwm_channel0, pwm_freq);
  // sigmaDeltaAttachPin(LED_BUILTIN, pwm_channel0);
  // sigmaDeltaWrite(pwm_channel0, pwm_value);
  ledcSetup(pwm_channel0, pwm_freq, 13);
  ledcAttachPin(LED_BUILTIN, pwm_channel0);
  Serial.begin(115200);
}

// 参考一下这位博主的函数输出函数
// 作者:济南凡事
// 链接:https://www.jianshu.com/p/7cef8e7b22d1
// 来源:简书
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {

  // calculate duty, 8191 from 2 ^ 13 - 1

  uint32_t duty = (8191 / valueMax) * min(value, valueMax);

  // write duty to LEDC

  ledcWrite(channel, duty);

}

// the loop function runs over and over again forever
void loop() {
  // for(i = 0; i < 255; i++){
  //   sigmaDeltaWrite(pwm_channel0, i);
  //   delay(10);
  // }
  // for(i = 255; i > 0; i--){
  //   sigmaDeltaWrite(pwm_channel0, i);
  //   delay(10);
  // }
  ledcAnalogWrite(pwm_channel0, pwm_value);
  pwm_value += add_value;
  if(pwm_value >= 250 || pwm_value <= 5){
    add_value = -add_value;
  }
  delay(10);
}

同样我们在这里介绍一下主要的几个函数

//初始化函数,下面的bit_num为设置的位数,那位博主设置为13位,可以再看一看上面的那个函数,加强理解
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
{
    if(chan > 15) {
        return 0;
    }
    double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
    _ledcSetupChannel(chan, LOW);
    return res_freq;
}


//引脚映射
void ledcAttachPin(uint8_t pin, uint8_t chan)
{
    if(chan > 15) {
        return;
    }
    pinMode(pin, OUTPUT);
    pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false);
}

最后,也算是成功完成,再次感谢。
在这里插入图片描述

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值