Problem of going into infinite loop

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

Hi all.

I am working in avr studio 4. Many times I suffer for this problem and I don't know what is happening. Many times when i make a code at some point it jumps to some invalid location / some invalid infinite loop. So here i create one example of code which can give you idea.

#include

#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#include
#include
#include 
#include 
#include

void usart_timer_init (unsigned int uintBaudRate,unsigned char ucharParity,unsigned char ucharStopbit);		//USART Timer INITIALIZATION Function


unsigned char uchararryDataString[20];

unsigned char ucharStringIndex=0;

unsigned char ucharStringFullFlag=0;

unsigned char ucharTimerCount;

int main(void)
{
DDRA=0x00;
usart_timer_init(9600,0,0);
sei();
PORTA=0xFF;

while(1)
{
while(1)
{
if (ucharStringFullFlag!=0)
break;
}

PORTA=~PORTA;
}

}


void usart_timer_init (unsigned int uintBaudRate,unsigned char ucharParity,unsigned char ucharStopbit)		//USART INITIALIZATION Function
{

//Define uintBuadRate as values like 4800,9600
//Define ucharParity as values like:
//				For none parity 0
//				For even parity 2
//				For odd parity 3
//			(if supplied any other value it will take initial values)
//Define ucharStopbit as values like
//				For one bit 0
//				For two bit 1
//			(if supplied any other value it will take initial values)
unsigned int uintUBRR;

uintUBRR = (F_CPU/uintBaudRate/16)-1;

if (ucharParity != 0 && ucharParity != 2 && ucharParity != 3)
	ucharParity = 0;

if (ucharStopbit != 0 && ucharStopbit != 1)
	ucharStopbit = 0;

// For Atmega8515
	UBRRH = (unsigned char)(uintUBRR>>8);
	UBRRL = (unsigned char)uintUBRR;
	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);		//RX interrupt Enable
												//RX enable
												//TX enable

	UCSRC = (1<<URSEL)|((ucharParity<<4) & 0x30)|((ucharStopbit<<3) & 0x08)|0x06;
												// define Asynchronous Mode
												// parity bit and stop bit character size
//-------- timer settings-------------------------------
//Timer 0 is used to generate 1.5 character delay. If communication lines are idle for more
//then this time it will flush RX input buffer. Please check your system does not using timer0

	ucharTimerCount=((F_CPU/1000)*64)/uintBaudRate;
	
	TIMSK|=0x02;					//TIMER0 INTERRUPT ENABLE
	TCNT0=ucharTimerCount;			//Timer delay for 1.5 character wait

}


SIGNAL(USART_RX_vect)									//ATmega8515

{
unsigned char ucharRX_data;							// RX buffer reg
	
	ucharRX_data = UDR;//store valid data in Rx buffer register
	

	if (ucharRX_data==0x05)
	{
	TCNT0= ucharTimerCount; // Reload count at every successful reception
	TCCR0=0x04; // turn on timer with prescaler of 256
	ucharStringFullFlag=1;
	}

	else
	TCCR0=0x00; // turn off timer

	uchararryDataString[ucharStringIndex++]=ucharRX_data;
	
}//serial USART interrupt end here
//####################################################################

//####################################################################
//Timer 0 overflow Interrupt ISR used for 1.5 character delay
ISR(TIMER0_OVF_vect)
{
	ucharStringIndex=0;

	TCCR0=0x00; // turn off timer

}//Timer 0 overflow interrupt end here

In this code if you debug you can see it goes into infinite loop @ below statement even if interrupt and timer overflows occur regularly.

if (ucharStringFullFlag!=0)
break;

When i build and run into avr simulator and i found this in disassembler window:

+00000061:   BA1A        OUT       0x1A,R1        Out to I/O location
27:       usart_timer_init(9600,0,0);
+00000062:   E880        LDI       R24,0x80       Load immediate
+00000063:   E295        LDI       R25,0x25       Load immediate
+00000064:   E060        LDI       R22,0x00       Load immediate
+00000065:   E040        LDI       R20,0x00       Load immediate
+00000066:   DFBB        RCALL     PC-0x0044      Relative call subroutine
28:       sei();
+00000067:   9478        SEI                      Global Interrupt Enable
29:       PORTA=0xFF;
+00000068:   EF8F        SER       R24            Set Register
+00000069:   BB8B        OUT       0x1B,R24       Out to I/O location
35:       if (ucharStringFullFlag!=0)
+0000006A:   91900061    LDS       R25,0x0061     Load direct from data space
+0000006C:   2399        TST       R25            Test for Zero or Minus
+0000006D:   F021        BREQ      PC+0x05        Branch if equal
39:       PORTA=~PORTA;
+0000006E:   B38B        IN        R24,0x1B       In from I/O location
+0000006F:   9580        LAT       R24            Load and Toggle
+00000070:   BB8B        OUT       0x1B,R24       Out to I/O location
+00000071:   CFFA        RJMP      PC-0x0005      Relative jump
+00000072:   CFFF        RJMP      PC-0x0000      Relative jump

so even if interrupt is there, portA will never toggle.

Herewith I am attaching zip file of my project in avr studio 4.18, WinAVR - 20100110.

This is one example. But many times i have suffered due to this kind of problems (every time i have to go through avr simulator's disassembler). I don't know if this is C why it is not working as i program. Is there any point missing in my code? Please help me. When i do long application based code this becomes headache. Thanks in advance

Attachment(s): 

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

FAQ#1

For more info click my sig to read the manual.

For even more info read Optimization and the importance of volatile in GCC

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

Yes When I changed variable to volatile then it gives defined result thank you very much you just saved a life.