ATtiny13Aを使ってリモコンのRGB LEDライトを作ろうとしています。
私はATtiny85がこの目的により適していることを知っており、最終的にコード全体に適合できない可能性があることを知っていますが、今のところ私の主な関心事はCTCモードで割り込みを使用してソフトウェアPWMを生成することです。
私は(と高速PWM以外の他のモードで動作することができないOCR0AようにTOP、私が使用していたIR受信コードは、それがCTCを使用して生成する38 kHzの周波数を必要とするため、基本的に同じものです)OCR0A=122。
だから私は(そしてインターネットでこれが言及されているのを見たことがあります)、ソフトウェアPWMを生成するために割り込みOutput Compare AとOutput Compare B割り込みを使用しようとしています。
OCR0AIRコードでも使用されるは、周波数を決定しますが、これは気にしません。そしてOCR0B、LEDの色を変更するために使用するPWMのデューティサイクルを決定します。
OCR0B値をから0に変更することで、デューティサイクルが0〜100%のPWMが得られると期待していますOCR0A。これは何が起こるべきかについての私の理解です:
しかし実際に起こっていることはこれです(これはProteus ISISシミュレーションからです):
以下を見るとわかるように、約25%〜75%のデューティサイクルを取得できますが、〜0-25%および〜75-100%の場合、波形はスタックし、変化しません。
黄色の線:ハードウェアPWM
REDライン:固定デューティサイクルのソフトウェアPWM
緑のライン:デューティサイクルが変化するソフトウェアPWM
そして、これが私のコードです:
#ifndef        F_CPU
    #define        F_CPU        (9600000UL) // 9.6 MHz
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main(void)
{
    cli();
    TCCR0A = 0x00;                        // Init to zero
    TCCR0B = 0x00;
    TCCR0A |= (1<<WGM01);                 // CTC mode
    TCCR0A |= (1<<COM0A0);                // Toggle OC0A on compare match (50% PWM on PINB0)
                                          // => YELLOW line on oscilloscope
    TIMSK0 |= (1<<OCIE0A) | (1<<OCIE0B);  // Compare match A and compare match B interrupt enabled
    TCCR0B |= (1<<CS00);                  // Prescalar 1
    sei();
    DDRB = 0xFF;                          // All ports output
    while (1)
    {
        OCR0A = 122;                      // This is the value I'll be using in my main program
        for(int i=0; i<OCR0A; i++)
        {
            OCR0B = i;                    // Should change the duty cycle
            _delay_ms(2);
        }
    }
}
ISR(TIM0_COMPA_vect){
    PORTB ^= (1<<PINB3);                  // Toggle PINB3 on compare match (50% <SOFTWARE> PWM on PINB3)
                                          // =>RED line on oscilloscope
    PORTB &= ~(1<<PINB4);                 // PINB4 LOW
                                          // =>GREEN line on oscilloscope
}
ISR(TIM0_COMPB_vect){
    PORTB |= (1<<PINB4);                  // PINB4 HIGH
}
          OCR0A私は持っているので、IRコードで使用されますOCR0B。3つの非PWMピンでソフトウェアPWMを生成するためにそれを使用しようとしています。
                
