Hey guys,
I've got a huge problem with passing arguments to an invoked function. It just doesn't work, at least sometimes... I can't figure out why this could possibly happen, but it does. My application is very small, just a few KB, thats why I dont assume there is a stack overflow or something like that. Any other guesses or maybe even solutions?
Thanks
show the code calling and the code called and elaborate on "huge problem". I can not even venture a guess as to what your actual problem is.
Erik
The called funcition is this one':
void UART_vTransmitArrayASCII(ubyte *TxValue, ubyte TxByteCount) { ubyte idata i=0; for (i=0;i<TxByteCount;i++){ UART_vTransmitASCII(*(TxValue+i)); } } // uart_transmit
and the calling function is this one
void TIMERS_vISR(void) interrupt 1 using 1 { ubyte DataPtr[3]={12,12,33}; ubyte DataCount=3; // disable timer 0 interrupt ET0=0; UART_vTransmitArrayASCII(DataPtr,DataCount); // reinitialize TH0 = 0x63; TL0 = 0xC0; // enable timer 0 interrupt ET0=1; } // timers_isr0 The problem is, that the value of TxByteCount is not the one of DataCount, but something else.
Despite the dubious implied multi-byte UART transmission from a timer ISR, doesn't UART_vTransmitArrayASCII() need to know about 'using 1' too?
I'm sorry, I don't understand where your going with this 'using 1'.... Could you explain it in more detail?
"... where your going with this 'using 1'..."
You qualified your ISR with 'using 1'. I'm suggesting that since some function parameters are passed in registers within a register bank, doesn't the called function need to know which register bank to use? Could it not knowing be the problem?
Also, could the timer ISR be getting reentered while the UART transmit function is executing?
"Also, could the timer ISR be getting reentered while the UART transmit function is executing?"
Never mind that. I see that you're disabling the timer interrupt while transmitting.
Good call Dan. Since the compiler uses absolure register addressing, I'd bet this is the problem.
In general, if you have an ISR that calls a function, that function must "use" the same register bank as the ISR.
Jon
Ok, great, thanks. I dind't know that, thougt always the compiler takes care of that.
Waht about functions the in the ISR called function calls, like UART_vTransmitASCII() in my case. Do I need to specify the register bank there according to the one used for the ISR, too?
Let me try one sentence: any function must have the same 'using' as the code it is called from.
does that answer your question?
"any function must have the same 'using' as the code it is called from."
And that includes the case of an ISR without any 'using' at all, the called functions would also lack any special qualifiers.
Ok, thanks for that again. So I removed all using x statements, since this is the simlest solution, and it still doesn't work propperly... Any othr guesses or am I not allowed to remove the using behind the ISR?
Best
Chris
Another thing, the KEIL Help File says:
The using attribute is most useful in interrupt functions. Usually a different register bank is specified for each interrupt priority level. Therefore, you could assign one register bank for all non-interrupt code, a second register bank for the high-level interrupt, and a third register bank for the low-level interrupt.
It doesn't mention anything about any function must have the same 'using' as the code it is called from and unfortunately this wasn't the problem im my application, too. But maybe I just got it all wrong;)
Any other guesses?
...any function must have the same 'using' as the code it is called from...
That's not EXACTLY correct. You can create registerbank-independent functions using the NOAREGS directive.
Refer to the following knowledgebase article for more informaiton:
http://www.keil.com/support/docs/598.htm