Dear all, I am completely stumped. I have a piece of code in which (normally) the process will not enter in to. It concerns a uart routine where it enters into the routine if a packet size has been detected. For some reason it enters into the routine even if there is no comm data. The variable(PacketSize) is previously initialized to "0". When the target device is powered up, I should have no output on the comm port. I do not recieve normal string data but garbage. Due to it sending anything at all I conclude that the variable PacketSize must be over written at some point. I have read on previous postings that it could have something to do with the pointers. I just can't figure out what. By the way, the simulator runs perfectly, the target device (AT89C51ED2) in a live enviroment gives the problem. Any advise will be welcome. Sorry if I'm not very clear in explaining the problem, it just that it's not that clear to me either.
void main(void) { InitVars(); com_baudrate (); while(1) { if (PacketSize > 0) { if (DecodeStringData()) { MainConveyorMotor = 1; SendComm("Hello", 0); } PacketSize = 0; } } } unsigned char DecodeStringData(void) { unsigned char i; unsigned short shReadCheckSum; unsigned char chMode; unsigned char chPos; unsigned short shChecksum; chMode = 0; chPos = 0; SBUF = PacketSize + '0'; shChecksum = calculateChecksum(&ReceivedPacket[1], PacketSize - 6); shReadCheckSum = 0; for (i = 1; i < (PacketSize - 1);i++) { if (chMode == 0) { // get command if ((ReceivedPacket[i] == ',') || (ReceivedPacket[i] == ';')) { Command[chPos] = 0; chPos = 0; if (ReceivedPacket[i] == ',') etc....etc....
void SendComm(unsigned char * pStringbuffer,unsigned char Stringlength) reentrant { idata unsigned char Ctr; if (Stringlength != 0) { for(Ctr=0; Ctr<Stringlength; Ctr++) { tbuf[t_in++] = pStringbuffer[Ctr]; } } else { for(Ctr=0; Ctr < 256; Ctr++) { if (pStringbuffer[Ctr] == 0) { break; } tbuf[t_in++] = pStringbuffer[Ctr]; } } if( t_in != t_out) { TI = 1; } }
PacketSize (and any other global variable shared between main and an interrupt handler) should be declared volatile.
Thanks for all the suggestions. I didn't have access to the live system today. I have already implemented the changes and will let you know how it goes. Regards John
if, indeed, (I believe it is so) that the ISR get pushes and pops when no 'using' is stated, you STILL have the problem, just now it is something else that get overwritten. Erik
Thanks for all the responses, The problem is solved. Drew was right, it was the volatile that needed to be added to the variables. Of course I did check all the other stuff, like adding the "using" (which I incedently had in the code before trying to find what was wrong). Anyways thanks everyone for the backup. Regards John Garrelts
"Drew was right, it was the volatile that needed to be added to the variables." Be aware that if any of these variables are larger than char then you'll need to do more than declare them volatile to ensure reliable operation.
Variables larger that char? So int and float is not protected with volatile, or are you talking about structures, arrays, etc...
Do a search on atomic and check out this tread. http://www.keil.com/forum/docs/thread2166.asp
"Variables larger that char? So int and float is not protected with volatile..." The 'volatile' keyword just prevents the compiler from optimising-away apparently redundant accesses - it does nothing to protect against the problems of interrupts, etc, interrupting non-atomic operations!