0
如果直接对定时器1进行编程(而不是通过库),并且可以将预分频器设置为1来运行,则可能会非常接近。理想情况下,你希望定时器的时钟周期为:
F_CPU / 15 kHz = 16,000 kHz / 15 kHz≈1066.67 CPU周期
如果将其舍入到最接近的整数,你将得到
F_CPU / 1,067 = 16,000 kHz / 1,067≈14.9953 kHz
这太慢了约0.03%,恰好在陶瓷谐振器对Uno计时的公差范围内。
这是我已经测试过的代码。
constexpr float PWM_FREQUENCY = 15e3; // 15 kHz
constexpr uint16_t PERIOD = round(F_CPU / PWM_FREQUENCY);
void setup() {
// Configure Timer 1 for 15 kHz PWM on pin 9 = PB1 = OC1A.
DDRB |= _BV(PB1); // set pin as output
TCCR1B = 0; // stop timer
TCCR1A = _BV(COM1A1) // non-inverting PWN on OC1A
| _BV(WGM11); // mode 14: fast PWM, TOP = ICR1
TCCR1B = _BV(WGM12) // ditto
| _BV(WGM13) // ditto
| _BV(CS10); // clock @ F_CPU
ICR1 = PERIOD - 1; // period
OCR1A = PERIOD / 4; // duty cycle
}
void loop(){}
收藏