我有一段代码用于在输出比较模式下使用快速pwm从PB4和PB5获得相同的模拟pwm输出电压。然而,它们的电压是不同的。可能是什么原因?此外,两个引脚的电压都接近1.23 V,这应该是输出电压应该是的。
这是代码。
#include <`avr/io.h`>
#include <`avr/interrupt.h`>
ISR(TIMER0_COMP_vect)
{
cli();
PORTB &= ~(1<<PB5);
sei();
}
ISR(TIMER0_OVF_vect)
{
cli();
PORTB |= (1<<PB5);
sei();
}
void init(void)
{
TCCR0 |= (0<<FOC0)|(1<<WGM01)|(1<<WGM00)|(1<<COM01)|(1<<COM00)|(1<<CS02)|(1<<CS01)|(1<<CS00);
OCR0 = 63;
TIMSK |= (1<<OCIE0)|(1<<TOIE0);
}
int main(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
init();
sei();
while(1);
}
答案 0 :(得分:1)
首先,如果您使用类似ATMega328p的东西,设置所有三个CS位将启用外部时钟源,而不是使用内部时钟,因此计时器不会运行(除非您实际上有一个外部定时器时钟源)。根据您使用的微控制器,确保这些位正在启用特定的预分频值。
其次,由于您的测量方法和PWM的实际工作方式,您可能还会遇到问题。虽然在处理Arduinos时它通常被列为模拟输出,但脉冲宽度调制实际上正如它所说的那样 - 它在地和VCC(可能是5V)之间快速切换数字输出,具有不同的占空比。如果在示波器上查看其中一个输出引脚,它可能会显示某种形式的方波。
使用万用表测量时,您看到的值将是输出为高或低的样本组合,可能是这些随机定时样本的平均值,因此意外读数。
要获得理想的结果,您确实需要平滑数字输出。简而言之,这通常使用低通滤波器,由连接到输出引脚的电阻和电容组成。
这通过使用方波在电容器高电平时通过电阻器对电容器充电,并在电容器电压低时放电。通过使更多时间高于低(更长的占空比),电容器稳定在更高的电压(反之亦然)。电阻器限制从AVR输出引脚吸取的电流(就好像电容器处于0V且输出被驱动为高电平,您可以立即有效地将输出短接到地)。
对于您的情况,一个大约4.7K的电阻和一个大约2uf的电容可能适合。增加电容或电阻以减少纹波。