arduino Mega 2560 PWM调频率(通过调节精度来实现)

没有示波器测量,理论上结果,有示波器的可以测一下,要是不对给我说下把帖子删了(别坑了其他人)。

(1)话不多说直接放程序

//Mega 2560 PWM调频率(通过调节精度来实现)1/8分频   
void setPwmFrequency(int pin,int precision){
  if(pin == 11 || pin == 12 || pin == 13){                  //timer 1(16位)
    TCCR1A = _BV(COM1A0)|_BV(COM1B1)|_BV(WGM11)|_BV(WGM10);
    TCCR1B = _BV(WGM13)|_BV(WGM12)|_BV(CS11);
    OCR1A = precision;
  }else if(pin == 10 || pin == 9){                           //timer 2(8位)
    TCCR2A = _BV(COM2A0)|_BV(COM2B1)|_BV(WGM21)|_BV(WGM20);
    TCCR2B = _BV(WGM22)|_BV(CS21);
    OCR2A = precision;
  }else if(pin == 5 || pin == 2 || pin == 3){               //timer 3(16位)
    TCCR3A = _BV(COM3A0)|_BV(COM3B1)|_BV(WGM31)|_BV(WGM30);
    TCCR3B = _BV(WGM33)|_BV(WGM32)|_BV(CS31);
    OCR3A = precision;
  }else if(pin == 6 || pin == 7 || pin == 8){               //timer 4(16位)
    TCCR4A = _BV(COM4A0)|_BV(COM4B1)|_BV(WGM41)|_BV(WGM40);
    TCCR4B = _BV(WGM43)|_BV(WGM42)|_BV(CS41);
    OCR4A = precision;
  }else if(pin == 46 || pin == 45 || pin == 44){            //timer 5(16位)
    TCCR5A = _BV(COM5A0)|_BV(COM5B1)|_BV(WGM51)|_BV(WGM50);
    TCCR5B = _BV(WGM53)|_BV(WGM52)|_BV(CS51);
    OCR5A = precision;
  }
}

/*输出频率 = 16M(时钟源)/8(分频数)/precision  通过调节precision来调节输出频率
**8位precision调节范围0-255,16位precision调节范围是0-65535
**precision的数值就是函数analogWrite()的上限值,不再是255。
*/

timer0有控制delay()这些计时函数的功能,改了之后会麻烦,就没加上。

寄存器控制引脚分配图:

**引脚中带A的(13引脚 OC0A)输出的频率是其他引脚(计算数值)的一半,占空比一直是50%,不要用analogWrite()调节这个引脚的数值。想知道原因的可以等下看下面链接中的其他帖子。

(2)需要调分频的可以根据这张图调节寄存器设置 ,增加频率的调节范围

 

 调节寄存器中CSn的数值来调节分频数;如上面的CSn1代表(第二位为1,从0开始算第一位)1/8分频,CSn2(第三位为1)1/256分频,以此类推。

寄存器控制图(图中是寄存器3)

(3)示例程序

void setup() {
 pinMode(45,OUTPUT);//OC5B
 pinMode(46,OUTPUT);//OC5A
 
 setPwmFrequency(45,100);//输出频率 16M/8/100 = 20k,46引脚是10k,
                         //每个寄存器设置一个引脚就可以
}

void loop() {
  //analogWrite(46,50); 不要写类似这样的,和这句OCR5A = precision;冲突
  analogWrite(45,40);//测出电压(2.0V)  没有示波器测不了频率,也不知道对不对
}
//Mega 2560 PWM调频率(通过调节精度来实现)1/8分频
void setPwmFrequency(int pin,int precision){
  if(pin == 11 || pin == 12 || pin == 13){                  //timer 1(16位)
    TCCR1A = _BV(COM1A0)|_BV(COM1B1)|_BV(WGM11)|_BV(WGM10);
    TCCR1B = _BV(WGM13)|_BV(WGM12)|_BV(CS11);
    OCR1A = precision;
  }else if(pin == 10 || pin == 9){                           //timer 2(8位)
    TCCR2A = _BV(COM2A0)|_BV(COM2B1)|_BV(WGM21)|_BV(WGM20);
    TCCR2B = _BV(WGM22)|_BV(CS21);
    OCR2A = precision;
  }else if(pin == 5 || pin == 2 || pin == 3){               //timer 3(16位)
    TCCR3A = _BV(COM3A0)|_BV(COM3B1)|_BV(WGM31)|_BV(WGM30);
    TCCR3B = _BV(WGM33)|_BV(WGM32)|_BV(CS31);
    OCR3A = precision;
  }else if(pin == 6 || pin == 7 || pin == 8){               //timer 4(16位)
    TCCR4A = _BV(COM4A0)|_BV(COM4B1)|_BV(WGM41)|_BV(WGM40);
    TCCR4B = _BV(WGM43)|_BV(WGM42)|_BV(CS41);
    OCR4A = precision;
  }else if(pin == 46 || pin == 45 || pin == 44){            //timer 5(16位)
    TCCR5A = _BV(COM5A0)|_BV(COM5B1)|_BV(WGM51)|_BV(WGM50);
    TCCR5B = _BV(WGM53)|_BV(WGM52)|_BV(CS51);
    OCR5A = precision;
  }
}

**记录学习用,侵权必删

 参考链接(建议观看)

arduino(mega2560)配置寄存器输出自定义频率pwm_比例失调的博客-CSDN博客_arduino pwm频率设置https://blog.csdn.net/weixin_51055384/article/details/124114222

arduino官方文档

https://docs.arduino.cc/tutorials/generic/secrets-of-arduino-pwm

动力老男孩

http://www.diy-robots.com/?p=852

arduino中文社区

https://www.arduino.cn/thread-19799-1-1.html

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值