问题描述
今天使用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);
}
最后,也算是成功完成,再次感谢。