Hello!
I'm programming two ATmega162s which should do some communication via their USART-interfaces. I'm using the C-programming language with the CodeVision AVR Compiler. I preferred C, because I do not have too much experience in programming in assembly language and to this point everything worked pretty good. But sadly a serious problem occured:
My Programm runs in an endless loop ("main-loop"), getting chars from the usart0 and putting them to usart1. This procedure is regulary (each 200ms) interrupted by Timer-Interrupt1 (CTC-mode), which puts a certain ping-signal ('*****') to usart1 and then starts Timer2(CTC-mode aswell), which Interrupts after 2ms. Within these two milliseconds 5 respond-chars should be received on usart1 in the main-loop. If not a certain PIN gets pulled down for some short time.
So far so good this seems to me to be a good idea. The Problem is, that TimerInterrupt1 would return to the main-loop, waiting for characters on usart0. In the case that at that time no char would arrive at usart0, the programm woulf be blocked by the corresponding getchar()-routine. So I put a longjump into the interrupt-routine1 to get to another place in the main-loop, where the ATmega then should wait for the ping-response at usart1. This all works, but it only works for 230 times receiving 'regular' characters on usart0 and putting them to usart1.
I suspect the stack of growing and growing, because the jump-operations, and I tested this. The Stack grows from somewhere 1275 to 837 and then the program hangs itself up. It would be nice, if someone could help me with that jump things....
Bye
Arnim
Here are the corresponding code excerpts:
....
#include #include #include
// Alphanumeric LCD Module functions #asm .equ __lcd_port=0x1B #endasm #include #include
....
//global vars char trans; char pingsent; char pongreceived = 0; char mode;
//debugging-vars int i = 0; int j = 0; int count_t1 = 0; int count_t2 = 0; char a[6], b[6], c[6]; int count_reset = 0;
//Processor-states according sot setjmp.h jmp_buf cpu_state;
//Functions char sendping(void); char receivepong(void);
....
interrupt [TIM1_COMPA] void timer1_compa_isr(void) { count_t1+=1; LED0_AN; mode=PING; pingsent = sendping(); TCCR2=0x0F; //start timer 2 LED0_AUS; //Longjump back to the main-loop longjmp(cpu_state, 1); }
// Timer 2 output compare interrupt service routine //2ms interrupt [TIM2_COMP] void timer2_comp_isr(void) { count_t2+=1; TCCR2=0x00; //stop itself TCNT2=0x00; //block next ctc-match if(pongreceived){ pongreceived = 0; } else { LED1_AN; //self-defined LED-ON delay_ms(10); LED1_AUS; //self-defined LED-OFF
} }//Interrupt Timer2
char sendping(){ int i; for(i=0;i