Newbie interrupt coding problem.

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm new to AVR programming, and working on a program to handle a small dot-matrix LED display. The CPU I'm using is the ATTiny43U, and I'm programming using the AVR Studio 5 and the AVR-GCC toolchain.

I'm trying to user Timer0 to trigger the row scanning code, but it's not working. From putting in some code to toggle an I/O pin, and looking at the results with an oscilloscope, I can confirm that the initialization code runs. My main program is just an empty while(1) loop. That loop runs, but only if I comment out the sei() macro that enables the interrupts. If the interrupts are enabled, the CPU resets as soon as the initialization completes.
Looking at the disassembly, the problem appears to be that the interrupt vector is not being properly set. The reset vector points to the start of my program, but all the other vectors point to a jump back to the reset vector. this means that the first time the timer triggers, the program restarts.
I'm obviously missing something somewhere, but what? Can anyone point out what I've missed?

This is the interrupt code. As far as I can tell, it's correct, it just never gets to execute.

ISR( TIMER0_COMPA_vect ) {
	unsigned int displaydata;
	
	PORTA = 0xFF;  // turn all rows OFF
	PORTB = 0x0F;
	row++; // point to next row data
	if ( row >= MAXROW ) {  // check for end of buffer array
		row = 0;
	}
	displaydata = Display_Buffer[row];
	PORTB &= ~(1<<PORTB7);  // chip select low for next command
    SPI_Transfer( 0x40 );   // writing to IO Expander #0
	SPI_Transfer( 0x14 );   // writing two registers, starting with address 0x14 (OLATA and OLATB)
	SPI_Transfer( displaydata & 0xFF );   // low byte of data to GPA
	SPI_Transfer( (displaydata>>8) & 0xFF  );   // High byte of counter to GPB
	PORTB |= (1<<PORTB7);   // chip select high to finish transfer
	switch (row) {   // turn on current row.
		case 0:
		    PORTA &= ~(1<<0);
			break;
			
		case 1:
		    PORTA &= ~(1<<1);
			break;
			
		case 2:
		    PORTA &= ~(1<<2);
			break;
			
		case 3:
		    PORTA &= ~(1<<3);
			break;
			
		case 4:
		    PORTA &= ~(1<<4);
			break;
			
		case 5:
			PORTA &= ~(1<<5);
			break;
			
		case 6:
			PORTA &= ~(1<<6);
			break;

		case 7:
			PORTB &= ~(1<<0);
			break;
			
		case 8:
			PORTB &= ~(1<<1);
			break;
			
		case 9:
			PORTB &= ~(1<<2);
			break;
			
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

While you do not say so, it sounds like you want to scan on each timer overflow. But, thats not the vector you have told it to use. That is NOT TIMER0_COMPA_vect Its more likely something along the lines of TIMER0_OVF_vect or something like that.

To find the complete set of vector names, the place to look is avrlibc manual. The names are different for different chips, so care is needed.

By the way, Studio5 is generally considered the least desirable of all the possible IDEs. Many bugs. I strongly recommend that you upgrade to the current version of Studio6.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Install an up to date Studio 6.1

Then Re-build and examine any Warnings.
Especially mis-spelled ISR()

You can run the program in the Simulator with a breakpoint in the ISR().

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems to me that the avr-gcc default ISR is the best choice for production,
but not so good for development.
The pseudo-reset effect seems to bite people a lot.
Admittedly calm thoughtful people would not be fooled.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Solved it! According to the ATTiny43U datasheet, table 10-1, the vector I need is TIMER0_COMPA. According to the AVR-GCC documentation, and the example assembly code in the ATTiny datasheet, the vector I need is TIM0_COMPA. The table appears to have the wrong name in it.
Strange how neither the compiler or the linker flagged that as an undefined symbol error, or even a warning.

Looks like the next step is going to be removing AVRStudio 5 and installing the latest version.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

, or even a warning.

Look again. If you get vector names wrong you will see a warning about "possibly misspelled vector name".

I built the code in the first post here for tiny43U and it said:

C:\Documents and Settings\asl\My Documents\Atmel Studio\test\test\test.c(5,88): 'TIMER0_COMPA_vect' appears to be a misspelled signal handler [enabled by default]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Strange how neither the compiler or the linker flagged that as an undefined symbol error
It does not produce a syntax error because the macro produces a legitimate C function. The only thing wrong with the invocation is that the linker won't know what vector to link it to.

Regards,
Steve A.

The Board helps those that help themselves.