ATMEGA328 and timer0 overflow

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

I'm finally looking into AVR studio 6. I tried a simple program using an ATTINY2313 and it seemed to work ok. I converted the small program over to the ATMEGA328 and now the timer0 overflow interrupt will not fire. The overflow interrupt does not happen in the simulator or on the chip. I setup the timer0 for overflow and then watch the TCNTO register count up to 0xFF in the simulator. When TCNTO reaches 0xFF, the TOVO flag is set in the TIFRO register. (The OCF0A and OCF0B are also set at the same time) Anyway, I never go into the SIG_TIMER0_OVF routine. (I saw the simulator has a bug if you single step over the SEI command, I'm not single stepping)
Here is my shortened code:

#include 
#include   //used to allow interrupts
#include     	//this file allows boolean data types in "C"
#include         //for the watchdog timer
#include 			//used for itoa routine
#include    //must be included to store arrays in FLASH
#include "main.h"	//defines, must be before the global variables since some global
#include "uart.h"		//routines for the serial port

//---------------------------------------------------------------------------
//Declare the data types
typedef unsigned char u08;  //A character, 8 bits
typedef unsigned short u16; //a short integer, big endian 16 bits, 0 to 65535
typedef bool ubool;         //a boolean, true or false, must include the header file "stdbool.h"

/*global variables*/
//Note:  Variables used in interrupts must be declared as volatile
volatile u16 uTock=defTock;	//A counter used for the 20mS tock
u08 u08State=0;		//the state for the state machine 
u08 uTmrState=10;	//a state timer

//----------------------------------------------------------------------------
//Routine:     main (the main loop of the program)
//
//Function:    This is where to program will execute until an interrupt happens or
//              someone yanks the power plug.
//
//Variables passed:
//       none
//Returns:
//       integer (no idea where this integer is returned to)
//----------------------------------------------------------------------------
// Main loop
int main( void )
{
	u08 u08Temp;
	
	uCinit();		//go through the initialization process for the microcontroller

	sei();        	//enable interrupts
	
	while(1)       // go into an infinite loop here
	{
       	SrvTock();        //go to the tock every 20ms
	}
	return 0;
}

//**************************************************************************
//----------------------------------------------------------------------------
//Routine:     	signal(SIG_TIMER0_OVf)  (timer 0 overflow)
//
//Function:    	This interrupt happens when timer 0 overflows
//
//Variables passed:
//       none
//Returns:
//       none
//----------------------------------------------------------------------------
SIGNAL(SIG_TIMER0_OVF)
{
	TCNT0=0;	//reset the counter
	PORTB |= (1<<0);
	PORTB &= ~(1<<0);
	if (uTock > 0)
	{
      uTock--;      //This counts down to a longer tock.  (a time reference for longer based timers)
	}	
}

//----------------------------------------------------------------------------
//Routine:      SrvTock  (Service the tock)
//
//Function:     Execute the tock every 20mS from the main loop.
//				This is where ALL the good stuff happens
//
//Variables passed:
//       none
//Returns:
//       none
//----------------------------------------------------------------------------
void SrvTock(void)
{
    if (uTock == 0)
    {
        uTock = 10;   //reload the Tock (20.65mS with a 1MHz clock) timer

        switch (u08State)	//This switch statement is the main state machine
        {		
			case 0:	//look at the pushbuttons to see if the output pulse width needs to change
			break;
		}
	}
}

//Routine:      uCinit (microcontroller initialize)
void uCinit(void)
{
	PORTB=0b00000000;	//to enable a pullup resistor on this port, set the bit to "1"
	DDRB=0b11111111;  	//to set the pin as an output, set the bit to "1"
	PORTD=0b11110001;     	//to enable a pullup resistor on this port, set the bit to "1"
	DDRD=0b00001110;   	//to set the pin as an output, set the bit to "1"

	//This sets up an 8 bit timer overflow
	TIMSK0 = (1<<TOIE0);	//Enable a timer overflow interrupt
	TCCR0A = 0;			//just a normal overflow
	TCCR0B = (1<<CS00);	//count with cpu clock/8

}


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

Grr.
I changed: SIGNAL(SIG_TIMER0_OVF)
to: SIGNAL(TIMER0_OVF_vect)
Now the ISR runs correctly.

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

Why do you use the long deprecated SIGNAL instead of ISR?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

\ should be / in includes

Why invent u08, u16 when stdint has uint8_t and uint16_t ?

As to your original SIGNAL problem - you must have got a warning about "misspelled handler name" - moral: never ignore warnings.

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

John: When I start a new project, I tend to go back and grab old source code as a start. I had not updated the SIGNAL yet.
Clawson: There is a warning, but I did not notice the warning buried in the 30 lines of output. Now, I see you can click on the "error list" tab to see the warnings/errors. (Avr studio 6 noob)

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

Try using -Werror which turns all warnings into errors that you simply cannot ignore.

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

clawson wrote:
Try using -Werror which turns all warnings into errors that you simply cannot ignore.

Awesome Feature with -pedantic (if you got too much time :D)