简体   繁体   English

带ATMega164PA的PWM

[英]PWM with ATMega164PA

I am trying to increase the brightness of an LED using PWM with Timer0 on the ATMega164PA. 我试图在ATMega164PA上使用带有Timer0的PWM来增加LED的亮度。 After running my code below the LED just stays emitted and doesn't vary its brightness. 在代码下方运行我的代码后,LED只会保持发光状态,并且不会改变其亮度。

Please take a look at my code and tell me if there is something I am doing wrong: 请查看我的代码,并告诉我是否做错了什么:

#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
}

I'm not sure of the logic of your approach, but I can see an obvious problem that is causing you difficulties. 我不确定您采用这种方法的逻辑,但是我可以看到一个明显的问题正在给您带来麻烦。

Integer division does not produce a fraction. 整数除法不会产生分数。 Instead, it rounds the result down to the nearest integer. 而是将结果四舍五入到最接近的整数。 This means that dutycycle / 100 will almost always be 0, since you ensure that dutycycle <= 100 . 这意味着dutycycle / 100确保dutycycle / 100几乎始终为0,因为您确保dutycycle <= 100 So OCR0A is almost always 0. The one exception is when dutycycle is exactly 100, which sets OCR0A to 255. 因此, OCR0A几乎始终为0。一个例外是dutycycle完全为100时,它将OCR0A设置为255。

One way around this is to use OCR0A = dutycycle * 255 / 100; 解决此问题的一种方法是使用OCR0A = dutycycle * 255 / 100; instead. 代替。 I don't know if this will fix all the problems, just the first one I see. 我不知道这是否可以解决所有问题,只是我看到的第一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM