我一直在 ATMega328P 上试验 PWM 波形生成模式。我得到了一些奇怪的结果,我不知道这是否与我编写固件或解释数据表的方式有关。
这是我为模拟analogWrite() 函数而编写的第一段代码:
// Waveform Generation Mode 0
// Table 15-4 of the datasheet
void setup()
{
DDRB = (1<<PB1); // set pin 9 as output
TCCR1A |= (1<<COM1A1);
OCR1A = 125;
}
void loop()
{
}
上面的代码从引脚 9 产生大约 2.5V(49% 占空比)的平均电压输出。奇怪的是(对我来说)根据数据表,TIMER1 是一个 16 位定时器,所以它应该在 65536 滴答时溢出. 据我了解,将 OCR1A 设置在 0 到 65535 之间会改变脉冲的占空比。那么,将 OCR1A 设置为 125,我不应该得到大约 0.01 V 而不是 2.5V 的输出吗?结果似乎暗示时钟在 255 处溢出。
对于我第二次涉足 PWM 领域,我想尝试使用 ATMega 的快速 PWM 模式创建一个 2.5V 信号。这是我得到的:
// Waveform Generation Mode 14
// Table 15-4 of the datasheet
void setup()
{
DDRB = (1<<PB1);
TCCR1A |= (1<<COM1A1) | (1<<WGM11);
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS10);
ICR1 = 19999;
OCR1A = 10000;
}
void loop()
{
}
我将 ICR1(溢出值)任意设置为 20000 个滴答声,然后将 OCR1A(比较值)设置为大约一半。我将通道 A 设置为非反相模式,但是(我认为)将其设置为反相模式不会有什么不同。当我把它刷到 Arduino 上时,我从引脚 9 获得了 5V(100% 占空比)的稳定电压平均值,但我终其一生都无法弄清楚原因。
我将不胜感激您能提供的任何见解。