Question

I am having trouble setting up high speed PWM on my ATtiny85. I need to use the PCK, at a speed of 400 kHz. I believe that I have followed the data sheet correctly, but for some reason, the timer interrupt flags are not working.

If I program the device, the output of the corresponding pin is a constant 5 V.

If I comment out the PCK setup and use the system clock instead, the flags are correctly set and PWM works fine. The code is posted. Why aren't the flags setting and the PWM isn't working?

#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{
    PORTB = 0;        //Reset values on port B

    // After setting up the timer counter,
    // set the direction of the ports to output
    DDRB |= (1<<PB1) | (1<<PB0); // Set the direction of PB1 to an output

    // PLLCSR - PLL control and status register:
    // PLL is a clock multiplier - multiplies system     8 MHz by 8 to 64 MHz
    // PLL is enabled when:PLLE bit is enabled,
    // CKSEL fuse is programmed to 0001.  This clock is
    //   switched off in sleep modes!
    PLLCSR |= (1<<PLLE);    // PLL enable

    // Wait until the PLOCK bit is enabled
    // before allowing the PCK to be enabled
    //WaitForPLOCK();
    //unsigned int i = 0;

    while ((PLLCSR & (1<<PLOCK)) == 0x00)
    {
        // Do nothing until plock bit is set
    }

    PLLCSR |= (1<<PCKE); // Enable asynchronous mode, sets PWM clock source


    TCCR1 =
            (1<<CTC1)    | // Enable PWM
            (1<<PWM1A)   | // Set source to pck
            (1<<(CS10))  | // Clear the pin when match with ocr1x
            (1<<COM1A1);
    GTCCR =   (1<<PWM1B) | (1<<COM1B1);


    // Set PWM TOP value - counter will count and reset
    //  after reaching this value
    //            OCR1C
    // 400 kHz    159
    // 450 kHz    141
    // 500 kHz    127
    OCR1C = 159;


    // Enable Timer1 OVF interrupt
    TIMSK = (1<<OCIE1A) | (1<<TOIE1);

    sei();

    // This should set the duty cycle to about 75%
    OCR1A = 120;
Was it helpful?

Solution 2

The errata (section 27 of the datasheet) states 'PLL will not lock under 6 MHz'. The only workaround listed is to set the clock to 6 MHz or higher.

OTHER TIPS

The solution involved the CKDIV8 fuse. To program this fuse correctly however, HVSP "High Voltage Serial Programming" was required. After removing this fuse so that the device operated at 8 MHz, the PWM gave a 400 kHz output. I hope other people find this useful!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top