NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Unexpected results using a timer interrupt and an LED

February 04, 2012
by dvdsnyd
dvdsnyd's Avatar

Hi guys, I have completed the base guide and have since started to dabble in interrupts. I was able to pretty well understand the real time clock tutorial. I was even able to look through the datasheet and see exactly which and why we set specific bits on the registers. So I decided to try something to extend that. I wanted to blink an LED every 1 second. Seemed pretty straightforward. Using the same 1024 prescaler, I figured instead of dividing that by 100, we would leave it at 14399((14745600/1024) -1) as the TOP value. Then it would be as simple as erasing all of the main loop code and replacing the interrupt with toggling the LED on and off. With all of that said, here is the code. Pretty straightforward...Here is the entire code

// main .c
// Flash an LED every 1 second using a timer interrupt
// Last Modified 2/4/2012
// Written By: David Snyder

// DEFINE STATEMENTS
#define F_CPU 14745600

// INCLUDE STATEMENTS

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

// PIN DEFINITIONS

// PC4 - RED LED

void initialize(){
    // Set up Timer0 for prescale and CTC mode
    // Set Prescale for Timer0 of 64
    TCCR0B |= (1<<CS02) | (1<<CS00);

    // Set CTC (Clear Timer on Compare)
    TCCR0A |= (1<<WGM01);

    // Set OCR0A to the value we want it to count/compare to
    OCR0A = 14399;

    // Enable interupt on compare event
    TIMSK0 |= (1<<OCIE0A);

    // Initialize ports for led
    DDRC |= (1<<PC4);
}

// Interupt
// Toggle Red LED to flash every 1 second
ISR(TIMER0_COMPA_vect){

    PORTC ^= (1<<PC4);
}

// Main Program
int main(){
    // Turn on global interrupt handler

    sei();

    // Run initialize routine
    initialize();

// Main Loop

while(1) {

}

}

So when I go to compile and program the MCU- I notice I get this warning: main.c:28: warning: large integer implicitly truncated to unsigned type

Which is referring to the OCR0A value of 14399.

It still compiles even with the warning, but when I flip the switch the red LED just stays illuminated. Which, to me means that the interrupt is firing way more than 1 time per second which is what I believe it to be. I basically confirmed this by just modifying the real time clock exercise- Pretty much just had to add the LED stuff. The time still increments and shows on the LCD. I guess my main question is, Why does it not act the way I think it should/ How would I get it to turn the LED on once per second. I am very new with interrupts/c programming. Even if I change the OCR0A number around, make it bigger that 14399, it still does not give it enough time to shut off/turn on. I believe that it is toggling, just too fast for the eye to see...

I am stumped with this. If someone could please show me where my logic is wrong/explain what is going on. It would be greatly appreciated.

Thanks so much in advance

David

February 04, 2012
by pcbolt
pcbolt's Avatar

Hi David,

I think part of the problem is that Timer0 is an 8-bit timer. The highest values any of the registers can use is 255 (decimal). Since you're trying to store a 16-bit value into it, only the low or high half of the 16-bit number will be used (I think it would be the low half). Since 14399 is 0x383f in hex, only 0x3f will be used (decimal 63). That would explain the "truncating" warning. You have two options to solve it:

First, just go back to 143 as the top value and add a global (and volatile) "count" variable. Increment it on each interrupt and test if it equals 100. If it does, blink the LED and reset "count" back to 0. If it is less than 100, do nothing.

Second, you could use Timer1, which I believe is a 16-bit timer. You may have to read the datasheet to see about accessing 16-bit registers, but it should not be hard.

Good luck.

February 04, 2012
by dvdsnyd
dvdsnyd's Avatar

Hi pcbolt,

Thanks a lot for the help. I quickly implemented the count method. Probably inferior to using the 16 bit timer, but it worked out perfectly. Thanks for the quick and helpful response. Your explanation made perfect sense to me. Appreciate it a lot!

David

Post a Reply

Please log in to post a reply.

Did you know that you can turn a $20 digital scale into a live weight sensor using our kit with a few extra parts? Learn more...