0

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

1 に答える 1

3

あなたのアプローチの論理はよくわかりませんが、あなたを困難にさせている明らかな問題があることはわかります。

整数除算は分数を生成しません。代わりに、結果を最も近い整数に丸めます。これはdutycycle / 100、 を保証するため、ほぼ常に 0 になることを意味しますdutycycle <= 100。SoOCR0Aはほぼ常に 0 です。唯一の例外は がdutycycle100 の場合で、これはOCR0A255 に設定されます。

これを回避する 1 つの方法は、OCR0A = dutycycle * 255 / 100;代わりに使用することです。これですべての問題が解決するかどうかはわかりませんが、最初に見た問題だけです。

于 2017-02-16T14:49:56.117 に答える