1
votes

My goal is to output a PWM signal from my ATtiny84 with 1ms high at 50hz. The clock is operating at 1mhz, so I've set the compare output mode such that the output pin should be cleared for 19000 clock ticks and be set for 1000.

The device is powered at 5V and I have an oscilloscope reading a flat 5V output from pin A5 (OC1B), no modulation. My code is here:

#include <avr\io.h>

void init_pwm_generator()
{
    PORTA &= ~(1 << (PORTA5));

    ICR1  = 20000;

    TCCR1A = (1<<COM1B1) | (1<COM1B0) | (1<<WGM11);
    TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10); 
}

int main(void)
{
    DDRA |=  (1 << (DDA5));

    init_pwm_generator();

    while(1)
    {   
        OCR1B = ICR1 - 1000;
    }
}

I can't figure out why this isn't working!

1
Just a quick thought: it seems to me that in your "while(1)" cycle you fiddle with the timer internal registers. I would let the timer alone. And... did you start the timer?linuxfan says Reinstate Monica
I tried moving the OCR1B line to the init function, but no change. Probably good to leave it out of the loop anyway. If I understand correctly, by setting CS10 (or any of the clock select bits), the timer should start running.Koraken
Take a look at andreasrohner.at/posts/Electronics/… , I hope it helps (I can not do more, not having an MCU of that kind at hands)linuxfan says Reinstate Monica

1 Answers

1
votes

See the datasheet chapter 12.5 Input Capture Unit at page 91

The ICR1 Register can only be written when using a Waveform Generation mode that utilizesthe ICR1 Register for defining the counter’s TOP value. In these cases the Waveform Genera-tion mode (WGM13:0) bits must be set before the TOP value can be written to the ICR1Register.

So, correct initialization sequence will be as follows:

    // Init the timer
    TCCR1A = (1<<COM1B1) | (1<COM1B0) | (1<<WGM11);
    TCCR1B = (1<<WGM13) | (1<<WGM12);

    ICR1  = 19999; // set the top value
    OCR1B = 19000; // set compare match value

    TCCR1B |= (1<<CS10); // start the timer

Please note, for the timer period to be 20000 ticks you have to set TOP value to 19999 (since the timer counts from zero)