ATmega32L reset during uart receiver isr

Status
Not open for further replies.

larten

Junior Member level 3
Joined
Aug 6, 2012
Messages
25
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,437
Hi,
I write a program for uart reciver with interrupt and LCD in code vision.
the baud rate of receiver is 250k.
there is a timer for write data to LCD using interrupt
when I program it my micro reset

I also write my data into lcd without interrupt and the resets will reduce.

what should I do?
 

what should I do?
Change occupation 8-O

Seriously, if there is something wrong don't you think that we need the code to see it in order to help?
Also check that the mcu model settings are correct in the codevision properties.
There may be hardware issues too.

Alex
 

Change occupation
That's a nice idea

here is my code
I use Atmega32L with 8MHz crystal and 20*4 lcd

Code:
interrupt [USART_RXC] void usart_rx_isr(void)
{
	char status,temp;
	#asm("cli")
	status=UCSRA;
	temp=UDR;
	
	//Break
	if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))!=0)
	{
		DmxRxstate=Break;
		PORTA.7=~PORTA.7;
		return;
	}
	
	//Start Code
	if (DmxRxstate==Break)
	{
		DmxRxstate=Data;
		//StartCode=temp;
		PORTA.6=~PORTA.6;
		Dmxcnt=0;
		return;
	}
	
	//Data
	if (DmxRxstate==Data)
	{
		if(Dmxcnt<channel)
		{
			Dmx_Data[Dmxcnt]=temp;
			Dmxcnt++;
			PORTA.5=~PORTA.5;
		}
		else
		{
			DmxRxstate=MarkBB;
			PORTA.4=~PORTA.4;
		}
		return;
	}
	DmxRxstate=MarkBB;
	#asm("sei")
}


interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
	char dmxstr[3],numstr[3];
	TCCR1B=0x00;
	//PORTA|=0x0F;
	//PORTA.3=~PORTA.3;
	#asm("cli")
	PORTD.4=1;
	Rx_dis;
	output=LCD_out;
	printf("number= %d\nDmx Rx ch10= %d",i,Dmx_Data[10]);
	i++;
	Rx_en;
	PORTD.4=0;
	#asm("sei")
	TCCR1B=0x03;
}
 

Did you check the model/memory settings i code vision?
Is there something in the board that can cause a reset (like a relay?)
 

Did you check the model/memory settings i code vision?
no
in the codewizard I chose Atmega32L and set my frequency
is there any other thing that I must check?

Is there something in the board that can cause a reset (like a relay?)
no there is only a LCD and MAX485 in my board
 

What about your stack size, can it be a problem?

Using recursive interrupts usually is not a good idea and can get out of hand, it can be the cause of the problem if a stack overflow occurs
 

What about your stack size, can it be a problem?

Using recursive interrupts usually is not a good idea and can get out of hand, it can be the cause of the problem if a stack overflow occurs
it's 512 byte

so you mean I should write my UART receiver sequentially?
 

In codevision the stack size is set manually in the project configuration, compiler tab.
 

In codevision the stack size is set manually in the project configuration, compiler tab.
I check it and it's 512 byte
I change it to 640 byte and it doesn't have any effect
 

If there is something wrong with the code and it gets stuck in recursive interrupts then you will get a stack overflow at some point no matter how high it is set, I have no idea if this is what happens in your case.

Have you tried a debugger to see the point where you get the reset?
 

Have you tried a debugger to see the point where you get the reset?
No I don't have any hardware debugger
and the code vision debugger won't work properly
 

Codevision doesn't have a debugger, it uses the debugger from AVR studio
 

so how should I use that?
I install atmel studio 6 and when I click on debugger of code vision atmel studio will open but there is an error that says "the following files were specified on the command line: receiver test_cof.aps these files could not be found and will not be loaded"
 

Your code is not commented and it's hard to analyze it but there's a subtle detail I realized from a first glance. You are using making use of the #asm("cli") and #asm("sei") commands. I don't know why you use them but it doesn't seem correct. Although AVR interrupts have priorities, they are prioritized only if they occur simultaneously. From this I mean a lower or higher priority interrupt cannot break into the ISR (Interrupt Service Routine) of another interrupt. Even if you have a valid reason for using the 'cli' and 'sei' commands inside the ISR, there exists a tiny bug in your UART ISR (usart_rx_isr). If the condition 'DmxRxstate==Data' is met, you return from the ISR without enabling the interrupts. See my comments below:

Code:
//Data
	if (DmxRxstate==Data)
	{
		if(Dmxcnt<channel)
		{
			Dmx_Data[Dmxcnt]=temp;
			Dmxcnt++;
			PORTA.5=~PORTA.5;
		}
		else
		{
			DmxRxstate=MarkBB;
			PORTA.4=~PORTA.4;
		}
		return;  // <-- Return from the ISR without enabling the interrupts.
	}
	DmxRxstate=MarkBB;
	#asm("sei")    // <-- Interrupts are enabled here!

So your current code may become in a state that interrupts get disabled in general. And maybe this state is what you define a 'reset'. I suggest you reconsider your usage of 'cli' and 'sei'.

Regards...
 

So your current code may become in a state that interrupts get disabled in general. And maybe this state is what you define a 'reset'. I suggest you reconsider your usage of 'cli' and 'sei'.

Regards...
the first time that I write this code there isn't any cli and sei but there are some reset and after that I added these codes

Your code is not commented and it's hard to analyze it
I write it for DMX512 receiver
I think if you know this portcol it's easy to understand
it has many state for send a packet
Mark before break that the line is idle (high)
break that the line become low for at least 50us
then line become idle again that called Mark after data
then there is a start code
after this there is 512 byte data
and after this is called Mark before data
 

Although AVR interrupts have priorities, they are prioritized only if they occur simultaneously. From this I mean a lower or higher priority interrupt cannot break into the ISR (Interrupt Service Routine) of another interrupt

If you are saying what I thing you are saying then this seems wrong.

The priority only affects interrupts which are triggered simultaneously or are pending, in these cases the interrupts are served at an order based on the priority they have (vector table order).
If you enable nested interrupts inside an interrupt then the interrupt can be interrupted from any interrupt, not just itself.
 

Using 'cli' thus generally disabling interrupts in an ISR has no effect as this bit is already cleared automatically when entering the ISR. The opposite (the 'sei' command) however enables the interruption of the ISR by another interrupt. From what I see you are not trying to enable the other interrupt to interrupt the currently executing ISR but trying to disable what is already disabled. I believe they are not needed in your code.

I write it for DMX512 receiver
I think if you know this portcol it's easy to understand
I don't know dmx512 protocol so I still don't know what your code is trying to achieve.

Regards...

- - - Updated - - -


Yeah, sry for missing information, I was talking about the default behavior, didn't want to go into the details of nested interrupts.

Regards...
 

So your current code may become in a state that interrupts get disabled in general. And maybe this state is what you define a 'reset'. I suggest you reconsider your usage of 'cli' and 'sei'.

Using 'cli' thus generally disabling interrupts in an ISR has no effect as this bit is already cleared automatically when entering the ISR. The opposite (the 'sei' command) however enables the interruption of the ISR by another interrupt.

That was the second point I was checking in order to be sure before replying but you have already corrected that in your second reply.
Once the interrupt has been executed it returns to the normal execution through the RETI (return from interrupt) command which restores the global interrupt flag so it doesn't really matter if you use cli inside an interrupt before it exits.

Alex
 

His code might get in a state with all interrupts disabled, that's not related to his usage of his 'cli' or 'sei'. I think the problem is his usage of 'return' in the condition (DmxRxstate==Data). I'm not sure how CodeVision compiles this line but returning from the interrupt with the 'ret' command instead of 'reti' doesn't set the GIE bit. He will need to check the assembler output. I have no idea how it is compiled, just a consideration.
 

Oh..OK, I though you meant that the problem was that we was returning before executing the sei command, I got confused with the text comments

return; // <-- Return from the ISR without enabling the interrupts.
}
DmxRxstate=MarkBB;
#asm("sei") // <-- Interrupts are enabled here!
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…