我试图通过ATMega164PA上的Timer0使用PWM来增加LED的亮度。在我的代码运行之后,LED只会保持发光并且不会改变其亮度。
请查看我的代码并告诉我是否有错误的事情:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int dutycycle = 0; // Variable for dutycycle
/********************************************** MAIN ****************************************************/
int main(void)
{
DDRB |= (1 << PB3); // Make pins output and OC0A pin for PWM
TCCR0A |= (1 << COM0A1) | (1<<WGM01) | (1<<WGM00); // Clear OC0A on comare match and set OC0A at BOTTOM
TIMSK0 |= (1<<TOIE0); // Overflow Interrupt Enabled
TCNT0 = 0; // Set Counter Value Register for comparison with OCR0A
OCR0A = (dutycycle / 100) * 255; // Set duty cycle ON period
sei(); // Enable global interrupts
TCCR0B |= (1 << CS00); // Prescale of 1 - start timer
while (1)
{
_delay_ms(500);
dutycycle += 10; // increase duty cycle by 10% every 500ms
if (dutycycle > 100) // if duty cycle is greater than 100% set to 0
{
dutycycle = 0;
}
}
}
ISR(TIMER0_OVF_vect)
{
OCR0A = (dutycycle / 100) * 255; // Set duty cycle ON period
}
答案 0 :(得分:3)
我不确定你的方法的逻辑,但我可以看到一个明显的问题导致你遇到困难。
整数除法不产生分数。相反,它将结果舍入到最接近的整数。这意味着dutycycle / 100
几乎总是0,因为您确保dutycycle <= 100
。所以OCR0A
几乎总是0.一个例外是当dutycycle
正好为100时,将OCR0A
设置为255。
解决此问题的一种方法是使用OCR0A = dutycycle * 255 / 100;
代替。我不知道这是否能解决所有问题,只是我看到的第一个问题。