AVR Silly Interrupt problem

I have timer0 set to overflow and generate an interrupt, but for whatever reason AVR Studio doesnt seem to be doing what the ISR is supposed to be doing! I'm attaching the code here, can you find something that I'm missing!?

Is this a problem with the simulation in AVR Studio or with the code itself? I haven't tested it on a device yet.

#include #include

ISR(TIMER0_COMP_vect) {

PORTA = 0xAA; TCNT0 = 0x00;

}

void init_timer(void) {

sei();

TCCR0 = 0x0D; // Force Output Compare Off - CTC mode - OC0 disconnected TCNT0 = 0x00; OCR0 = 0xA0; // Overflow at 0xA0; TIMSK = TIMSK | 0x02 ; // Generate interrupt on Overflow

TIFR&=~(1

Reply to
jasimpson
Loading thread data ...

I'm using/simulating on an AtMega32, btw.

-Jim

Reply to
jasimpson

You're mixing up overflows and compares.

So this is a handler for the Compare event.

While you are enabling the overflow interrupt.

Find out the difference between Compare and Overflow in the datasheet and your the king.

Meindert

Reply to
Meindert Sprang

Oh crap, I wish you were right!

But that was a mistake in my commenting! TIMSK = TIMSK | 0x02 corresponds to setting OCIE0, which enables the Output Compare Match Interrupt which I believe is what I'm trying to catch with ISR(TIMER0_COMP_vect).

I have checked with AVR-LIBC over and over to make sure that that is the right name for Output compare on an AtMega32.

Thanks though. But I'd appreciate it if you could look over it one more time. Thanks again.

Reply to
jasimpson

Ok, the code seems to be OK then. I noticed you have a prescaler value of

1024. With a compare value of 0xA0, that is 163,840 clockcycles. Are you waiting long enough? You might want to speed up the simulation by choosing a lower prescaler value, like no prescaling at all.

Meindert

Reply to
Meindert Sprang

Since the vectors for different AVRs are in different locations (as far as I remember), are you compiling for the same processor as you are simulating with.

I spent ages doing exactly that some time ago. Everything compiles but when the interrupt occurs, the wrong vector was fetched for the interrupt routine.

If you induce an interrupt and single step through the call, where do you end up?

Pete Harrison

Reply to
Peter Harrison

I changed it to no prescaler and its still doing the same thing - even after I wait for a while..

Reply to
jasimpson

Pete,

I might be having the same problem as you did. But:

1) How do I check which processor I'm compiling for? I know that I specified in AVR Studio that I am targeting (simulating?) for an AtMega32.

2) I'm relatively new to AVR Studio, How do I induce an interrupt when simulating?

Thanks again! Jim

Reply to
jasimpson

Well, somewhere you must have included a processor specific include file that defines the interruptvector number you used in the declaration of the interrupt handler:

ISR(TIMER0_COMP_vect) {

PORTA = 0xAA; TCNT0 = 0x00;

}

TIMER0_COMP_vect must be declared in a processor-specific file. The vector address is processor dependent.

Meindert

Reply to
Meindert Sprang

Meindert,

I'm using AVR-LIBC libraries and got the vector name from:

formatting link

which I believe corresponds to the interrupt.h file that i've included.

-Jim

Reply to
jasimpson

I am not familiar with WinAVR - sorry

arrange things so that you are single-stepping in the compiled code while viewing the disassembled version. In the left pane, be sure you are looking at the processor IO.

Run the code to the endless loop and start to single-step. Now you can manually set the overflow/interrupt flags in the IO view. Step your code again and the interrupt will occur. There are more sophisticated ways but that will work (I expect).

Pete

Reply to
Peter Harrison

Right - got it now

Your project should have a MakeFile. If not, you can set the processor on the compiler command line but I really don't know what you have to do. You will have to ask someone else how all that works sorry.

In the makefile will be some lines like this:

# MCU name32 MCU= atmega32 # speed required by avr/delay.h F_CPU= 8000000

That is where the compiler gets to find out which processor you are using.

Pete

>
Reply to
Peter Harrison

Pete,

I single stepped and forced an interrupt in the I/O view like you mentioned and something interesting happens!! Instead of going to the ISR for the corresponding interrupt (Timer0 compare match), the next step takes to me to "int main (void) {" !!! Which means that the system is getting reset by the interrupt everytime!?

And the Timer seems to be running fine. Cause if I let the code Auto Step, I can see TCNT0 incrementing till OCR0 (0xA0) and the program being reset-ed.

Which should make you think that the vector name I've specified is not correct. Right? But I'm using the same vector name that AVR-LIBC tells me to and the same code!!!!

What do you think is going on?

Oh, and I checked the Makefile and the MCU = atmega32 and I'm simulating for atmega32 too.

Do you think I should test it in hardware now instead of wasting time simulating?

Thanks, Jim

Reply to
jasimpson

Have you actually CHECKED if the vector is the right one? Look at the address of the code and compare it with the vector list in the datasheet.

No, the simulator is perfectly capable of simulating timer interrupts. I do it too.

Meindert

Reply to
Meindert Sprang

I don't know what compiler or environment you are using but, for this program to work for me ( I use WinAVR - GCC 3.4.3 ), the first few lines or the source file need to look like this:

#include #include #include

//ISR(TIMER0_COMP_vect) SIGNAL(SIG_OUTPUT_COMPARE0) { PORTA = 0xAA; TCNT0 = 0x00; }

I have no ISR macro defined and the SIGNAL macro needs the signal.h file to be included. Without that, there are compiler errors. I would expect you to be getting those errors as well. They may look like warnings only but they are fatal to the execution of your program. You are asking the compiler to create a function called ISR. It does not know that it is meant to be an interrupt service function so does not put an entry into the interrupt vector table. Consequently, the table is probably full of zeros causing the processor to jump to address zero when the interrupt occurs. This is functionally the same as a soft reset.

Pete

Reply to
Peter Harrison

Note that I seem to be using an older AVR-LIBC than you. Nevertheless, the outcome should be much the same.

I think

pete

Reply to
Peter Harrison

I'm using WinAVR - AVR GCC 3.4.3 and AVR-LIBC 1.2.3

and they recommend using ISR() over SIGNAL() or INTERRUPT()..

But I'm downloading the latest version of WinAVR cause I have a feeling that 1.2.3 is probably too old of an AVR-LIBC version.

-Jim

Reply to
jasimpson

OMG IT FINALLY WORKS!!!

Yes, I was using an old version of AVR-LIBC which had not started supporting ISR() yet.

I downloaded the latest version 1.4.3 and it fixed the problem!

Thanks a lot Mike and Pete for walking me through this weird problem.

-Jim

Reply to
jasimpson

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.