Custom Delay function using arduino IDE - c

I'm in a microprocessors class and we're writing our own delay functions that are actually accurate. Our professor gave us, what I assume is, a 4 ms delay function. I don't really understand how to transfer that to a .25 s or a 1 s delay, which are both needed for my homework.
The given function is as follows(Assume _BV() is defined as _BV(x) 1<<(x)):
DDRB |= _BV(1);
TCCR1A |= _BV(COM1A0);
TCNT1 = 0;
OCR1A = 100;
TIFR1 = _BV(OCF1A);
TCCR1B |= _BV(CS10);
while((TIFR1 & _BV(OCF1A)) == 0);
TIFR1 = _BV(OCF1A);
OCR1A = 100 + 64000;
while((TIFR1 & _BV(OCF1A)) == 0);
TCCR1B = 0;
TCCR1A = 0;
I've written the code needed to complete the homework except the two delay functions.
Here is what I have so far:
#include <avr/io.h>
uint8_t numIN;
void setup() {
Serial.begin(9600);
DDRB |= _BV(5);
}
void loop() {
int i;
numIN = 10;
Serial.println("Enter a number between 0 and 9.");
do {
while (Serial.available() > 0)
{
numIN = Serial.read() - '0';
if (numIN < 0 || numIN > 9)
{
Serial.println("Input Error!");
}
}
} while (numIN < 0 || numIN > 9);
Serial.print("You entered ");
Serial.println(numIN);
if (isEven(numIN))
{
for (i = 0; i < 5; i++)
{
PORTB |= _BV(5);
delay(1000); //temporary
//delay_Sec();
PORTB &= ~_BV(5);
delay(1000); //temporary
//delay_Sec();
}
}
else
{
for (i = 0; i < 5; i++)
{
PORTB |= _BV(5);
delay(250); //temporary
//delay_quarterSec();
PORTB &= ~_BV(5);
delay(250); //temporary
//delay_quarterSec();
}
}
}
void delay_quarterSec(void)
{
//need to finish
}
void delay_Sec(void)
{
//need to finish
}
boolean isEven(int num)
{
if (num & _BV(0))
return false;
else
return true;
}
I'm just confused how I take my professor's code and transfer it to what I need to do. Any help is greatly appreciated!

I can give you a quick overview about what the provided code does.
(This is from memory, so don't take my word for it. And you don't mention your controller type. You will have to look up the registers up in detail.)
DDRB |= _BV(1); // set the compare match output pin to output
TCCR1A |= _BV(COM1A0); // enable output compare PIN toggle
TCNT1 = 0; // set counter start value to 0
OCR1A = 100; // set compare match value to 100 (the actual delay)
TIFR1 = _BV(OCF1A); // clear the output compare flag
TCCR1B |= _BV(CS10); // enable the timer by setting the pre-scaler
while((TIFR1 & _BV(OCF1A)) == 0); // wait until the timer counted to 100 (compare flag is set again)
So the actual delay depends on:
the setting of the prescaler
the clock speed of your controller
the value of OCR1A
Example:
If the prescaler is set to 1 and you run at 10MHz you got
t = (1 / (10000000/s)) * 100 = 10us
This should get you started.

Related

Programming of built in timer of arduino

I am new to programming in IDE. I am using built-in timer of arduino.I am using TDR method to capture reflection from fault location in cable and for that I am using timer.Timer should start as soon as output is send and stop at reflection. I have a reference code for it but I dont able to understand it, so if anyone know about it , it would be great.
void setup()
{
pinMode(stepPin, OUTPUT);
pinMode(refPin, OUTPUT);
pinMode(shutdownPin, OUTPUT);
TCCR1A = 0;
TCCR1B = (1 << ICNC1); // input capture noise canceller enabled, capture on falling edge
TIMSK1 = 0; // timer 1 interrupts disabled
ACSR = 0; // input capture from ICP1 pin
TCCR2B = (1 << CS20); // change timer 2 PWM frequency to 31.25kHz because we're using pin 11 as a DAC
Serial.begin(19200);
}
struct Step
{
unsigned int time;
unsigned int amplitude;
};
// Take a single measurement, using either a positive or negative edge from the comparator.
// The comparator reference voltage must have been set up and allowed to stablise before calling this.
unsigned int takeMeasurement(bool posEdge)
{
byte reg1b = (posEdge) ? 0 : (1 << ICES1); // input capture noise canceller csdisabled, set up input capture polarity, stop timer
reg1b |= (1 << CS10);
TCCR1B = reg1b;
TCNT1H = 0;
TCNT1L = 0; // clear timer
unsigned int capture = 0;
unsigned long start = micros(); // get the time
cli();
TCNT1H = 0;
TCNT1L = 0; // clear timer
TIFR1 = (1 << ICF1); // clear timer 1 input capture bit
PORTD |= (1 << 4); // set output high
sei();
do
{
if ((TIFR1 & (1 << ICF1)) && capture == 0)
{
byte temp = ICR1L;
capture = (ICR1H << 8) | temp;
}
} while (micros() - start < 100);
PORTD &= ~(1 << 4); // set output low
return capture;
}
size_t findSteps(bool positive, struct Step *results, size_t maxResults)
{
byte amplitude = (positive) ? 5 : 250;
analogWrite(refPin, amplitude);
delay(100); // wait 100ms for the output to stabilise
unsigned int lastReading = 0;
size_t numResults = 0;
unsigned int stepSize = 0; // 0 means not in a step
#ifdef DEBUG
Serial.print((positive) ? "pos " : "neg ");
#endif
for (int i = 0; i < 50; ++i)
{
analogWrite(refPin, amplitude);
delay(10);
unsigned int currentReading = takeMeasurement(positive);
unsigned int currentDiff = currentReading - lastReading; // diff since start of possible step
if (stepSize == 0)
{
// Not currently in a step
if (i != 0 && currentReading != 0 && currentDiff == 0)
{
// Found the start of a possible step
++stepSize;
}
lastReading = currentReading;
}
else
{
if (currentDiff > 2 || i + 1 == 50)
{
// Step has endeed, so record it if it is big enough
if (stepSize >= 2)
{
results->time = lastReading;
results->amplitude = amplitude - 5;
++results;
++numResults;
if (numResults == maxResults) break;
}
stepSize = 0;
lastReading = currentReading;
}
else if (currentDiff == 0)
{
++stepSize;
}
}
#ifdef DEBUG
if (i != 0) Serial.write(',');
Serial.print(currentReading);
#endif
if (positive)
{
amplitude += 5;
}
else
{
amplitude -= 5;
}
}
#ifdef DEBUG
Serial.println();
#endif
return numResults;
}

attiny13 pwm led complete on off

Sorry for my english. I have some issues on attiny13 with pwm. pwm works perfectly on adjustment. However while OCR0B value is going to zero or max, led not complete off or on. I tried use " PORTB &= ~ (1<<); " while OCROX was zero, but it doesnt work. afterwards I find that I must add " ISR(TIM0_COMPA_vect)" for interrupt. I have recently begun work on tiny ,so its too hard especially avr side for me and pls ignore my illiteracy. This is code, ı used.
#define F_CPU 1200000
#define LED PB1
#include <avr/io.h>
const int buttonPin = 4; // the pin that the pushbutton is attached to
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 1;
int model; // previous state of the button
void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the LED as an output:
}
void adc_setup (void)
{
// Set the ADC input to PB2/ADC1
ADMUX |= (1 << MUX0);
ADMUX |= (1 << ADLAR);
// Set the prescaler to clock/128 & enable ADC
// At 9.6 MHz this is 75 kHz.
// See ATtiny13 datasheet, Table 14.4.
ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}
void pwm_setup (void)
{
// Set Timer 0 prescaler to clock/8.
// At 9.6 MHz this is 1.2 MHz.
// See ATtiny13 datasheet, Table 11.9.
TCCR0B |= (1 << CS01);
// Set to 'Fast PWM' mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);
// Clear OC0B output on compare match, upwards counting.
TCCR0A |= (1 << COM0B1);
}
void pwm_write (int val)
{
OCR0B = val;
}
void button()
{
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
model = buttonPushCounter % 5 ;
} else {
// if the current state is LOW then the button went from on to off:
}
// Delay a little bit to avoid bouncing
delay(250);
}
lastButtonState = buttonState;
}
int main (void)
{
int adc_in;
// LED is an output.
DDRB |= (1 << LED);
adc_setup();
pwm_setup();
while (1) {
// Get the ADC value
button();
//adc_in = adc_read();
// Now write it to the PWM counter
switch(model)
{
case 0:
pwm_write(0);
//PORTB &= ~ (1<<PB3);
break;
case 1:
pwm_write(50);
break;
case 2:
pwm_write(100);
break;
case 3:
pwm_write(150);
break;
case 4:
pwm_write(255);
//PORTB |= (1<<PB3);
break;
}
}
}
I find another code successfully turn on, off and adjust led via using interrupt with two button, but I dont understand how code write values on OCR0X. Could somebody can explain me the connection between OCR0X and duty(count, pwm value) at the second code . Because ı need write constant values in those OCR0X.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define PWM_PIN PB0
#define KEY_UP_PIN PB1
#define KEY_DOWN_PIN PB2
#define PWM_DUTY_MIN (0)
#define PWM_DUTY_MAX (100)
#define PWM_DUTY_STEP (1)
#define KEY_UP (1 << 1)
#define KEY_DOWN (1 << 2)
static volatile uint8_t duty = 0;
static uint8_t counter = 0;
static void process(void);
static uint8_t read_keys(void);
ISR(TIM0_COMPA_vect)
{
if (duty > PWM_DUTY_MIN && duty < PWM_DUTY_MAX) {
if (counter == 0) {
PORTB |= _BV(PWM_PIN);
} else if (counter == duty) {
PORTB &= ~_BV(PWM_PIN);
}
if (++counter == PWM_DUTY_MAX) {
counter = 0;
}
}
}
int
main(void)
{
/* setup */
DDRB |= _BV(PWM_PIN); // set PWM pin as OUTPUT
PORTB |= _BV(KEY_UP_PIN)|_BV(KEY_DOWN_PIN);
TCCR0A |= _BV(WGM01); // set timer counter mode to CTC
TCCR0B |= _BV(CS00); // set prescaler
OCR0A = 95; // set Timer's counter max value (96 - 1)
TIMSK0 |= _BV(OCIE0A); // enable Timer CTC interrupt
sei(); // enable global interrupts
_delay_ms(100); // time of debounce
/* loop */
while (1) {
process();
_delay_ms(8);
}
}
void
process(void)
{
uint8_t keys;
if (!(keys = read_keys())) {
return;
}
if ((keys & KEY_UP) && duty < PWM_DUTY_MAX) {
duty += PWM_DUTY_STEP;
}
if ((keys & KEY_DOWN) && duty > PWM_DUTY_MIN) {
duty -= PWM_DUTY_STEP;
}
if (duty == PWM_DUTY_MIN) {
PORTB &= ~_BV(PWM_PIN);
} else if (duty == PWM_DUTY_MAX) {
PORTB |= _BV(PWM_PIN);
}
}
static uint8_t
read_keys(void)
{
uint8_t result = 0;
if ((PINB & _BV(KEY_UP_PIN)) == 0) {
result |= KEY_UP;
}
if ((PINB & _BV(KEY_DOWN_PIN)) == 0) {
result |= KEY_DOWN;
}
return result;
}

How can the average of the ADC Readings be calculated?

The aim is to store the newest 10 ADC readings in an array and then calculate the average of them to be used elsewhere. Removing the oldest each time it is updated.
Regarding the LED timing, it must switch timing from 1s to 0.25s if ADC reading is within boundaries as written below, how can this be implemented correctly? I know my method works but can be done better.
As for the LED's they must change patterns if a switch is pressed as you can see, which they do, but yet again I'm sure it can be done another simpler way!
Below is my code, Also I'm sure there are many an error and plenty of room for optimization, I will gladly accept it all!
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int timecount0;
unsigned int adc_reading;
volatile uint32_t timing = 1;
volatile uint32_t accumulator = 0;
volatile uint16_t average = 0;
volatile uint16_t samples = 0;
#define LED_RED PORTB = ((PORTB & ~0b00001110)|(0b00000010 & 0b00001110))
#define LED_GREEN PORTB = ((PORTB & ~0b00001110)|(0b00001000 & 0b00001110))
#define LED_BLUE PORTB = ((PORTB & ~0b00001110)|(0b00000100 & 0b00001110))
#define LED_RGB PORTB = ((PORTB & ~0b00001110)|(0b00001000 & 0b00001110))
#define DELAY_COUNT 6
volatile uint8_t portdhistory = 0xFF;
void Timer0_init(void)
{
timecount0 = 0; // Initialize the overflow count. Note its scope
TCCR0B = (5<<CS00); // Set T0 Source = Clock (16MHz)/1024 and put Timer in Normal mode
TCCR0A = 0; // Not strictly necessary as these are the reset states but it's good
// practice to show what you're doing
TCNT0 = 61; // Recall: 256-61 = 195 & 195*64us = 12.48ms, approx 12.5ms
TIMSK0 = (1<<TOIE0); // Enable Timer 0 interrupt
PCICR |= (1<<PCIE0);
PCMSK0 |= (1<<PCINT0);
sei(); // Global interrupt enable (I=1)
}
void ADC_init(void)
{
ADMUX = ((1<<REFS0) | (0<<ADLAR) | (0<<MUX0)); /* AVCC selected for VREF,ADLAR set to 0, ADC0 as ADC input (A0) */
ADCSRA = ((1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(7<<ADPS0));
/* Enable ADC, Start Conversion, Auto Trigger enabled,
Interrupt enabled, Prescale = 32 */
ADCSRB = (0<<ADTS0); /* Select AutoTrigger Source to Free Running Mode
Strictly speaking - this is already 0, so we could omit the write to
ADCSRB, but included here so the intent is clear */
sei(); //global interrupt enable
}
int main(void)
{
ADC_init();
Timer0_init();
DDRD = 0b00100000; /* set PORTD bit 5 to output */
DDRB = 0b00111110; /* set PORTB bit 1,2,3,4,5 to output */
sei(); // Global interrupt enable (I=1)
while(1)
{
if(!(PIND & (1<<PIND2)))
{
PORTD = PORTD |= (1<<PORTD5);
PORTB = PORTB |= (1<<PORTB4);
if(average>512)
{
PORTB = PORTB |= (1<<PORTB5);
}
}
else
{
PORTD = PORTD &= ~(1<<PORTD5);
PORTB = PORTB &= ~(1<<PORTB4);
}
}
}
ISR(TIMER0_OVF_vect)
{
TCNT0 = 61; //TCNT0 needs to be set to the start point each time
++timecount0; // count the number of times the interrupt has been reached
if(!(PIND & (1<<PIND3)))
{
if (timecount0 >= 0) // 40 * 12.5ms = 500ms
{
PORTB = ((PORTB & ~0b00001110)|(0b00000000 & 0b00001110));
}
if (timecount0 >= 8*timing)
{
LED_RED;
}
if (timecount0 >= 16*timing)
{
LED_GREEN;
}
if (timecount0 >= 24*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00000110 & 0b00001110));
}
if (timecount0 >= 32*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001000 & 0b00001110));
}
if (timecount0 >= 40*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001010 & 0b00001110));
}
if (timecount0 >= 48*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001100 & 0b00001110));
}
if (timecount0 >= 56*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001110 & 0b00001110));
}
if (timecount0 >= 64*timing)
{
timecount0 = 0;
}
}
else
{
if (timecount0 >= 0)
{
PORTB = ((PORTB & ~0b00001110)|(0b00000000 & 0b00001110)); //ALL OFF
}
if (timecount0 >= 8*timing)
{
LED_RED;
//PORTB = ((PORTB & ~0b00001110)|(0b00000010 & 0b00001110)); //RED
}
if (timecount0 >= 16*timing)
{
LED_GREEN;
}
if (timecount0 >= 24*timing)
{
LED_BLUE;
}
if (timecount0 >= 32*timing)
{
timecount0 = 0;
}
}
}
ISR (ADC_vect) //handles ADC interrupts
{
adc_reading = ADC; //ADC is in Free Running Mode
accumulator+= adc_reading;
if ((adc_reading > 768) & (adc_reading <= 1024))
{
timing = 10;
}
if ((adc_reading >= 0) & (adc_reading<= 768) )
{
timing = 2.5;
}
samples++;
if(samples == 10)
{
average = accumulator/10;
accumulator = 0;
samples = 0;
}
}
Depending on your processors, you may way to keep ISR() speedy and avoid expensive /,%.
The LED stuff, I'd handle in a timer interrupt.
#define N 10
volatile unsigned sample[N];
volatile unsigned count = 0;
volatile unsigned index = 0;
volatile unsigned sum = 0;
ISR (ADC_vect) {
if (count >= N) {
sum -= sample[index];
} else {
count++;
}
sample[index] = ADC;
sum += sample[index];
index++;
if (index >= N) {
index = 0;
}
}
unsigned ADC_GetAvg(void) {
block_interrupts();
unsigned s = sum;
unsigned n = count;
restore_interrupts();
if (n == 0) {
return 0; //ADC ISR never called
}
return (s + n/2)/n; // return rounded average
}
I'd recommend an integer version of a low pass filter than the average of the last N.
In terms of the moving averaging w/ N = 10, chux - Reinstate Monica has provided the solution. Chux - Reinstate Monica also recommends looking at an integer version of a low pass filter. I personally like the Exponentially Weighted Moving Average (EWMA) because it's fairly simple to code and only requires a few values to do the averaging. This is compared to having to hold 10 in array in your case. I would recommend Elliot Williams's Make: AVR Programming Chapter 12 for this. In case you don't have access to this readily, the EWMA, as explained in Make AVR, starts with
y_current = (1/16)*x_current + (15/16)*y_previous
where in our case, y_current is the updated EWMA value, x_current is the newest sample from your ADC, and y_previous is the last EWMA value. The choice of 16 can also be changed along with the weights, 1 and 15. Keeping it a power of 2 is important though, as you will see. As shown in Elliot Williams book, you multiply by 16 and compensate for rounding problems and get the following,
16*y_current = x_current + 16*y_previous - (16*y_previous - 8)/16.
Now, I know this looks ugly but what we have is scaled by 16 average value that's an integer and only relies on integer addition (the 16*y_previous is stored as one value so you don't do the multiplication) and a bit shift; that's the reason why a power of 2 was chosen in the EWMA, dividing by 16 is the same as a right bit shift of 4. Ok, so what does this average look like in code:
// Snippet from Make: AVR Programming
uint16_t x_current; // ADC value.
uint16_t y_current; // Average ADC value.
// Get the EWMA.
y_current = x_current + y_current - ((y_current - 8) >> 4);
// Send the value over USART (assuming it's wired up). Remember that
// y_current is scaled by 16.
printf("%d\n",(y_current>>4));
The above is just the EWMA that you can use in your code and an example of sending it, which is just a reminder that the value if scaled. Remember, this is just the averaged ADC value. Likely you will be wanting to use the ADC value as an input to a function to get the value of some measured quantity. Rather than actually using a function and calculating values, you can create a look-up table where the index is the ADC value and the array entry at that index is the precalculated value.
In terms of your other code, the things that could be corrected/streamlined are in your ISRs. In ISR(TIMER0_OVF_vect) you have some bit operations that are constant and can be precalculated so that your not doing it everytime the ISR(TIMER0_OVF_vect) fires.
PORTB = ((PORTB & ~0b00001110)|(0b00000000 & 0b00001110));
becomes
PORTB = ((PORTB & 0b11110001)|(0b00000000)); // Saves a bit inversion and '&'
which shows that your ORing, |, doesn't affect the result, because you're ORing against all zeros.
Finally, in your ISR (ADC_vect) you are using the bitwise, &, and not the logical and, &&. You get the same result but it's like using a wrench to hammer in a nail. I know this is a lot but I hope it helps and let me know if you need clarification.

ATMega48 - how to register an external PCINT2 interruptor?

I'm currently trying to create a simple program for an ATMega48 emulator that has a PCINT2 external interruptor listening on PORTD input and changing the output based on its value.
Here's the code of the interruptor:
unsigned int d; // a variable that has to change based on the input
ISR(PCINT2_vect) {
if (PORTD % 2 == 0) {
if (d <= 8000) {
d += 500;
}
} else {
if (d >= 1000) {
d -= 500;
}
}
}
the main() function:
int main(void)
{
DDRD = 0x00; // set PORTC for input
DDRB = 0xFF; // set PORTB for output
PORTB = 0x00; // Initial value is 0
PCMSK0 = 0b00000100;
d = 4000;
sei();
while (1) {
// Enable\Disable the LED with an initial delay
if (PIND == 0b00000000) {
PORTB = 0b00100000;
} else {
PORTB = 0b00000000;
}
// Delay for N seconds (determined by interrupt)
delay_stuff(d);
}
return 1;
}
Currently it's not calling the interruptor no matter what happens to any port, my assumption is that I'm not registering some magical ATMega listeners to call the interruptor.
How to register the interruptor then, what am I missing here?
According to datasheet page 75-76, you must enable Pin Change Interrupt in PCICR register and select which pin will be enabled on the corresponding IO in PCMSK2 for PCINT2 (PCMSK0 is for PCINT0, i.e PINB).
int main(void)
{
DDRD = 0x00; // set PORTC for input
DDRB = 0xFF; // set PORTB for output
PORTB = 0x00; // Initial value is 0
PCICR |= _BV(PCIE2); //or, PCICR |= 0x04;
PCMSK2 |= 0xFF; //any changes in PIND will trigger interrupt
d = 4000;
sei();
//other codes...
}

blinking led continuously with 1 second in C language(atmega328p)

I am using AVR Studio5 to program the arduino uno rev3 with atmel atmega328p.Now , I am trying blink a led continuously within 1 second .
The code is :
PORTD = 0b10001010;
TCNT1H = 0xBB;
TCNT1L = 0xBB;
TCCR1A = 0;
TCCR1B = 5; // prescaler is 1024
while((TIFR1 & (1<<TOV1)) == 0)
{
temp = TCNT1H;
while ((TCNT1H - temp) >= 11);
PORTD ^= 1<<7; // blinking as expected
}
TIFR1 = 1<<TOV1;
TCCR1A = 0;
TCCR1B = 0;
The above code shows that I use a timer1 lasting for 1 second in which I attempt to blink the PORTD.7 led for each 0.032768s.
But , now , the problem is that the timer works for delaying 1 second but the led keep lighting without blinking . Please help .
( P.S the circuit works fine )
Complement :
If I use the following code , it shows the led blinking.
for ( a = 0;a<2;a++)
{
PORTD = 0b00001010;
TCNT1H = 0xEE;
TCNT1L = 0xEE;
TCCR1A = 0;
TCCR1B = 5; // prescaler is 1024
while((TIFR1 & (1<<TOV1)) == 0);
TIFR1 = 1<<TOV1;
TCCR1A = 0;
TCCR1B = 0;
PORTD = 0b10001010;
TCNT1H = 0xEE;
TCNT1L = 0xEE;
TCCR1A = 0;
TCCR1B = 5; // prescaler is 1024
while((TIFR1 & (1<<TOV1)) == 0);
TIFR1 = 1<<TOV1;
TCCR1A = 0;
TCCR1B = 0;
}
But , for the simplicity , I prefer the most top method if working .
while ((TCNT1H - temp) >= 10)
{
PORTD ^= 1<<7; // blinking as expected
}
You are blinking too fast, so fast that actually what are you are seeing is a LED with half the luminosity. You need to add some delay between two invocations of PORTD ^= 1<<7.
This is something that should be done with an interrupt.
void TMR_init(void)
{
DDRD|=_BV(PD7); //bit 7 of port D to output
TCNT1=0; //reset the timer counter
OCR1AL=0xC6; //depends on your osc. This values are for 12MHz
OCR1AH=0x2D; //with 12 000 000Hz / 1024 it takes 11718 ticks for 1 sec->0x2D C6
TIMSK1|=_BV(OCIE1A); //enable interrupt on output compare A (when timer value == value in the OCR1AL/H-registers)
TCCR1A=0; //normal operation
TCCR1B=_BV(CS12) | _BV(CS10); //prescaler 1024 and starts the timer
sei(); //enable interrupts
}
//isr
SIGNAL(TIMER1_COMPA_vect)
{
PORTD^=_BV(PD7); //toggle
}
This code should work but is untested. Don't forget to include avr/interrupt.h. Some macros may differ due to version differences of the compiler.

Resources