我爱编程结构化 · 科技

使用Arduino Uno输出自定义频率的PWM

2018-04-23  本文已影响0人  一森一森

摘要

现在需要用Arduino输出可自定义频率(100Hz)的PWM来控制电动机转速。Arduino里有简单的语句来实现PWM,但是输出信号的频率不能更改。本文结合网上的文章信息和我的研究结果,解释一下实现频率可调的PWM的过程。

PWM

PWM(Pulse Width Modulation)是一种方波控制信号。方波高电平的宽度在一个周期里的占比被称为占空比(Duty Cycle)。改变PWM的占空比,可以改变输出信号的平均电压,实现模拟电压的输出。

Arduino里的PWM

首先,Arduino Uno的5,6,9,10,3,11接口可以通过简单语句analogWrite(pin, dutyCycle)来实现一个指定占空比的PWM。其中pin的值选择(5,6,9,10,3,11),dutyCycle的值在0~255之间,0为占空比0%,255为占空比100%。但是这种方式PWM信号的频率是固定的默认值,大约1000Hz左右(16MHz/64/256)。

其次,手动切换高电平和低电平,再在中间加入delay函数,可以实现自定义频率的PWM:

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(13, HIGH);
  delayMicroseconds(100); // Approximately 10% duty cycle @ 1KHz
  digitalWrite(13, LOW);
  delayMicroseconds(1000 - 100); //修改这里的1000可以调整频率
}

但是,这种操作需要CPU全神贯注的查数,任何其他的进程的干扰会导致输出的信号频率不准。

综上,需要底层的手段来控制Arduino实现PWM的频率调节。

调节Arduino里的时钟频率

Arduino Uno里有三个Timer:Timer0,Timer1,Timer2。 三个Timer都可以自定义调整频率,但是各有特点。Timer0负责控制delay等函数,动了Timer0的频率会导致计时函数不准;Timer1的计数器是16位的,和Timer0,Timer2的8位计数器不太一样;Timer2的频率可调的档位更多,因为它有7档预除数,下文会进一步解释。这里选择Timer2进行调节操作,先上代码:

void setup() {
  // put your setup code here, to run once:

  pinMode(3, OUTPUT); 
  pinMode(11, OUTPUT); 
  
  TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); //Set Timer2 to varying top limit fast PWM mode
  TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20);//another way to set prescaler CS2=fff
  
  OCR2A = 155; //Top value A
  OCR2B = 30; //Toggle value B, Output at pin 3
 
  //CS2  Divisor  Frequency
  //001    1        31372.55
  //010    8        3921.16
  //011    32       980.39
  //100    64       490.20   <--DEFAULT
  //101    128      245.10
  //110    256      122.55
  //111    1024     30.64
}

void loop() {
  // put your main code here, to run repeatedly:

}

由以上代码可见,需要的设置分为三个部分:pinMode,TCCR2A/B,OCR2A/B(这里的2是因为选择了Timer2)。

频率计算

到这里,所有设置已经解释完。下面来计算一下100Hz输出的PWM具体参数应该设为多少。
pin3的输出频率=16MHz / 1024/ (OCR2A + 1),因此100Hz对应的OCR2A=155。(+1是因为fast PWM是从0开始数到上限值)
占空比 = (OCR2B+1)/ (OCR2A+1),所以:

占空比 OCR2B值
20% 30
25% 38
33% 51
50% 77
100% 155

总结

至此,本文介绍了如何使用Arduino的Timer时钟功能自定义设置PWM的频率和占空比。简要解释了Timer的选择,输出管脚的确定,比较寄存器的设定,计数器的预除数选择和模式选择。最后演示了100HzPWM的个参数计算过程。

References

  1. http://www.diy-robots.com/?p=852
  2. http://www.righto.com/2009/07/secrets-of-arduino-pwm.html
  3. http://playground.arduino.cc/Main/TimerPWMCheatsheet
  4. http://www.geek-workshop.com/thread-25012-1-1.html

2019年6月补充

实验结果.jpeg

如图中所示,在setup()中设置好计数器以后,loop()为空,在示波器中Pin3读出的PWM波形频率为100Hz,占空比为21.67%,约为20%。经检测目标达成。


如果这篇文章对你有所帮助,还请帮忙点赞打赏评论分享~谢谢


上一篇 下一篇

猜你喜欢

热点阅读