AT90CAN128 resetting??

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

I have used following code to generate delays of 70 milliseconds and 55 milliseconds respectively using TIMER1 of AT90CAN128 using output compare method. I am facing one problem that after timer 1 initialization, the uC seems to 'reset' after an elapse of certain amount of time(at TCNT1 = 0x0105). I have tried debugging the code in simulator mode and with JTAG ICE both. The problem is same in both the cases. While debugging with simulator and JTAG ICE both, I observed that the control was reaching at the start of 'main' function immediately on entering 'sonarINIT' function. Please refer the attached screenshot of the AVR Studio containing my code in debug mode.

I am using AT90CAN128 with AVR Studio and WinAVR. Debugger is JTAG ICE.

#include
#include
#include

#define F_CPU 16000000L
#define BAUD 9600

volatile uint8_t usart_global = 0;
volatile uint8_t delay70msFlag = 1;
volatile uint8_t delay55msFlag = 1;

void USART1_Init() 
{ 
  /* Set baud rate */ 
  UBRR1H = (unsigned char) (((F_CPU/(16L*BAUD))-1) >> 8); 
  UBRR1L = (unsigned char) ((F_CPU/(16L*BAUD))-1); 

  /* Set frame format: 8data, no parity & 1 stop bits */ 
  UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (0<<USBS1) | (3<<UCSZ10); 

  /* Enable transmitter and receiver */ 
  UCSR1B = (1<<TXEN1)|(1<<TXCIE1);
 
}

ISR(USART1_UDRE_vect)
{
    UDR1 = usart_global;
    UCSR1B &= ~(1<<UDRIE1);
}

ISR(TIMER1_COMPA_vect)
{
    delay70msFlag = 0;
    delay55msFlag = 0;
}
void delay70ms()
{
    OCR1A = 0x1116;

    /* Set the timer1 output compare A interrupt flag */
    TIMSK1 |= (1<<OCIE1A);

   /* select Timer/Counter1 prescaler. 16MHz/256 */
   TCCR1B = (0 << CS12) | (1 << CS11) | (1 <<CS10); 
    
}

void delay55ms()
{

   OCR1A = 0x0D6D;

     /* Set the timer1 output compare A interrupt flag */
    TIMSK1 |= (1<<OCIE1A);

    /* select Timer/Counter1 prescaler. 16MHz/256 */
   TCCR1B = (0 << CS12) | (1 << CS11) | (1 <<CS10); 
    
}

void sonarINIT() /* The control reaches at start of 'main' after reaching here */
{                  
    PORTB |= (1<<PB7);
}

void disableSONAR()
{
    PORTB &= ~(1<<PB7);
}

void main()
{
    	USART1_Init();
	sei();
    
	while(1)
	{
	    usart_global = 0xAC;
	    UCSR1B |= (1<<UDRIE1);

	    sonarINIT();
	    delay70ms();
	    while(delay70msFlag);

	    /* Disable the timer */
            TCCR1B &= 0xF8;

	    delay70msFlag = 1;
	    usart_global = PORTB;
	    UCSR1B |= (1<<UDRIE1);

            disableSONAR();
	    delay55ms();
	    while(delay55msFlag);

	    /* Disable the timer */
            TCCR1B &= 0xF8;

	    delay55msFlag = 1;
	    usart_global = PORTB;
	    UCSR1B |= (1<<UDRIE1);

            usart_global = 0xCA;
	    UCSR1B |= (1<<UDRIE1);
        }
}

Kindly help.

Attachment(s): 

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

The UCSR1B register TXCIE1 bit enables the UCSR1A register TXC1 interrupt, which is ISR(USART1_TX_vect).

The ISR(USART1_UDRE_vect) that you did put in your code uses the UCSR1B register UDRIE1 enable bit.

You are enabling the USART1_TX_vect interrupt, except you are not providing any interrupt handler. Because you never provided the correct ISR, any TXC1 event causes GCC to execute the BADISR vector and reset.

If you set AVRStudio to breakpoint on the 0x44 interrupt vector address for USART1 Tx, you should be able to see this bug when it happens.

In the future, if you include this ISR function:

ISR(BADISR_vect)
{
// user code here
}

and set a breakpoint on the user code, your JTAGICE debugging will catch any bad interrupt event and warn you about this type of problem. Then you just have to figure out if an unused interrupt got triggered and if so, which one got triggered.

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

Hey Mike. thanks a lot. It's working now :)

I observed that I made a mistake while choosing a prescaler too. Prescaler is Clko/256 so the prescaler selection shall look like:

TCCR1B = (1 << CS12) | (0 << CS11) | (0 <<CS10); 

instead of(what was in the original code that was posted):

TCCR1B = (0 << CS12) | (1 << CS11) | (1 <<CS10);

Thanks again.