EmbDev.net

Forum: µC & Digital Electronics Atmega32U16 - PWM - No output


von LustigerGeselle (Guest)


Rate this post
0 useful
not useful
Dear friendly,

I am currently trying to dim LEDs by applying PWM on the LEDs' supply 
voltage.
My setup is:
- Atmega32U16
- usbasp Programmer (chinese)
- 16 MHz external crystal
- hfuse c9, lfuse 3f
- External interrupts on INT0, INT1, INT2
- Use of Timer0 for more sophisticated interrupt handling

Here's the relevant part of my init code (for whole main see bottom):
int main(void) {
    ...

    // use OC1B as output, Pin D4
    DDRD |= (1 << PD4);

    // non-inverted output, toggle OC1B on compare match
    TCCR1A |= (1 << COM1B0) | (1 << WGM10) | (1 << WGM11);

    // select OCR1B is TOP for WGM10:3 == 1; detemine counting sequence
    TCCR1B = (1 << WGM12) | (1 << WGM13);


    OCR1B = 0; // toggle on TCNT1 == 0
    OCR1A = 7811; // set TOP value for PWM1A, toggle on TCNT1 = 7811

    // select prescaler 1024, start timer
    TCCR1B |= (1 << CS12) | (1 << CS10);

    ...

    for(;;) { ... }

    return 0;
}

This should imo produce a pulsed output with a frequency 1Hz on port 
OC1B. Thus, if I connected a LED to Pin D4, it should toggle every 1 
second.
BUT, sadly, that does not happen. I'd very much appreciate any advice on 
how to make it work.
[c]
int main(void) {
    // CTC mode Timer0
    TCCR0 |= (1 << WGM01);
    // select prescaler 1024
    TCCR0 |= (1 << CS00) | (1 << CS02);
    // interrupt @625Hz
    OCR0 = 25 - 1;
    // use internal CPU interrupt vector
    TIMSK |= (1 << OCIE0);

    // activate OC1B as outputs (PIN D4)
    DDRD |= (1 << PD4);

    // non inverted output, toggle on compare match
    TCCR1A |= (1 << COM1B0) | (1 << WGM10) | (1 << WGM11);
    // select OCR1B is TOP for WGM10:3 == 1; detemine couting sequence

    TCCR1B = (1 << WGM12) | (1 << WGM13);

    // set TOP value for PWM1A
    OCR1B = 0;
    OCR1A = 15383;//PWM_MAX-1;

    // select prescaler 1024
    TCCR1B |= (1 << CS12) | (1 << CS10);

    // select external interrupts INT0, INT1, INT2
    MCUCR = (1 << ISC01) | (1 << ISC11);

    // enable fetching interrupts
    GICR |= (1 << INT0) | (1 << INT1) | (1 << INT2);

    // enable interrupt service routines
    sei();

    DDRC |= 0xff;

    for (;;) {
        PORTC++;
        _delay_ms(50);
    }

    return 0;
}
[\c]

von LustigerGeselle (Guest)


Rate this post
0 useful
not useful
Found the solution. The datasheet says

"WGM13:0 = 15: Toggle OC1A on Compare Match, OC1B disconnected (normal 
port operation)."
That is why
DDR |= (1 << PD4); // This would activate disconnected OC1B
TCCR1A |= (1 << COM1B0) ...; // cannot toggle disconnected Pin OC1B
does not make much sense. Fixed this by using PD5 and (1 << COM1A0):
    DDRD |= (1 << PD5);

    // non inverted output, toggle on compare match
    TCCR1A |= (1 << COM1A0) | (1 << WGM11) | (1 << WGM10);
    // select OCR1B is TOP for WGM10:3 == 1; detemine counting sequence
    TCCR1B |= (1 << WGM12) | (1 << WGM13);
    // select prescaler 1024
    TCCR1B |= (1 << CS12) | (1 << CS10);

    OCR1A = TOP-1;

von c-hater (Guest)


Rate this post
0 useful
not useful
LustigerGeselle wrote:

> Found the solution.

Congrats

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig