是否可以使用Arduino产生精确的15 kHz时钟脉冲?
0 905
0

我想使用Timer1使用Arduino生成15 kHz脉冲,但是问题是,如果我们想要15000 Hz的时钟,则需要使用1/15000秒或66.66微秒来初始化计时器,但是我们只能传递不带小数的整数Timer1.initialize(66);函数产生15155 Hz频率的精度。

那么,是否可以通过其他任何方式生成精确的15000 Hz或15000 Hz-15155 Hz之间的频率?

#include <TimerOne.h>

void setup() {
  pinMode(9,OUTPUT);
  Timer1.initialize(66);  // Frequency, 100 µs = 10 kHz
  Timer1.pwm(9,255);
}
 
void loop() {}
收藏
2021-02-05 11:02 更新 蝈蝈 •  224
共 1 个回答
高赞 时间
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(){}

收藏
2021-02-05 11:04 更新 我爱喝牛奶G •  2074