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):
1 | int main(void) {
|
2 | ...
|
3 |
|
4 | // use OC1B as output, Pin D4
|
5 | DDRD |= (1 << PD4);
|
6 |
|
7 | // non-inverted output, toggle OC1B on compare match
|
8 | TCCR1A |= (1 << COM1B0) | (1 << WGM10) | (1 << WGM11);
|
9 |
|
10 | // select OCR1B is TOP for WGM10:3 == 1; detemine counting sequence
|
11 | TCCR1B = (1 << WGM12) | (1 << WGM13);
|
12 |
|
13 |
|
14 | OCR1B = 0; // toggle on TCNT1 == 0
|
15 | OCR1A = 7811; // set TOP value for PWM1A, toggle on TCNT1 = 7811
|
16 |
|
17 | // select prescaler 1024, start timer
|
18 | TCCR1B |= (1 << CS12) | (1 << CS10);
|
19 |
|
20 | ...
|
21 |
|
22 | for(;;) { ... }
|
23 |
|
24 | return 0;
|
25 | }
|
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]