I've an Atmega328p and I've connected an LED to it's D4 pin and I want it to turn LED on/off every one second.
I found this tutorial and I've change it base on some online AVR timmer calculator and the 12MHZ external crystal which I've used, to this :
#define F_CPU 12000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
DDRD |= 1 << 4;
PORTD |= 1 << 4;
ICR1 = 0xB71B;
TCCR1B |= (1 << WGM12);
// Mode 4, CTC on OCR1A
TIMSK1 |= (1 << ICIE1);
//Set interrupt on compare match
TCCR1B |= (1 << CS12);
// set prescaler to 256 and starts the timer
sei();
// enable interrupts
while (1)
{
// we have a working Timer
}
}
ISR (TIMER1_COMPA_vect)
{
PORTD |= 0 << 4;
// action to be done every 200ms
}
The LED is always on or off no mater how I change ICR1 value. How can I make it work?
The timer initialization looks fine (see other answer), but it looks like you are not toggling the LED correctly.
PORTD |= 0 << 4;
will do nothing.
Assuming you drive the LED directly, use PORTD |= (1 << 4);
to turn LED on, PORTD &= ~(1 << 4);
to turn LED off and PORTD ^= (1 << 4);
to toggle the output state.
Since you just want to toggle the LED state, the last option is obviously the best choice, because you do not have to check the current state of the output pin to decide if you need to switch on or off.