2004-05-24 01:47 AM
2011-05-17 03:00 AM
In the serial example code, I see that the transmit method,
forces the software to wait until all characters are transmited. I tried to set the t_in1 index to the last charater in the buffer, then set TI=1 and EA=1. and inside the interrupt, before exiting set again TI=1, to make it re-enter the isr and transmit the next chracter until t_out == t_in. well this way it doesn't work. is there a way to make it work?2011-05-17 03:00 AM
While we have not done it yet, it should be possible to modify the ISR function to send only one character at a time while in the interrupt.
2011-05-17 03:00 AM
I made this work, with just a small correction to the ISR:
if (TI != 0) { TI = 0; if (t_in != t_out){ SBUF = tbuf [t_out++]; while(!TI); // Added line }else t_disabled = 1; } } I added the line: while(!TI); // Added line and it made the difference. now the transmit function needes only to set: EA=0; t_out = 0; t_in = strlen(tbuf); EA=1; TI=1; from this point the whole buffer will be transmitted automatically.2011-05-17 03:00 AM
steadicopter,
That will certainly work, but the line while(!TI) make the function blocking. That is, essentially, no other code will execute until your ISR is done sending every character. If you remove the while loop, you can certainly have the ISR transmit one character at a time and let some other code execute until the buffer's ready for another. The trick is to NOT set TI=1 on your own. The system will set this bit whenever a character has finished transmitting and will vector to the interrupt to have your ISR load up the next one. If you prefer doing things your way, a better thing to do would be to disable the interrupt altogether and just transmit them in some other function. This would save you returning from and immediately vectoring back to the interrupt and get your transmitting done quicker. Best Regards, Phaze4262011-05-17 03:00 AM
Thanks for the replay,
I understand this theory, and it should work without the line: while(!TI); but what this does is, it prints only the first character of the buffer. It looks like it doesn't enter the interrupt the second time TI changes to 1. How could this be? (i posted my initializations on 06-05-2004 at 16:31 ) [ This message was edited by: steadicopter on 19-05-2004 10:52 ]2011-05-17 03:00 AM
steadicopter,
Throw this into your initialization somewhere: IE |= 0x10; to make sure the serial interrupt is enabled. Then, once you've got your in and out pointers set, set TI=1 just like you do now. Then make your interrupt something like the following: if (TI) { TI=0; if (t_out != t_in) { SBUF = tbuf[t_out++]; } else { /* disable tx */ } } and that really should transmit every byte. If it doesn't then something somewhere ELSE in the program is probably going on with your in and out counters. Let me know if that works. Regards, Phaze4262011-05-17 03:00 AM
so everything was OK with the interupt after all.
I removed the while(!TI) line, and it works fine now. the problem was that with the interrupt it was fast enough to get to the next time the program starts to fill the transmit buffer (0.2sec). so I just use different buffers one for the program and one for the interrupt. and just before starting transmit I copy the buffer to the transmit buffer. Thanks for the help. It helped me alot.2011-05-17 03:00 AM
steadicopter,
No problem at all, but if you'll indulge, I have a bit of preaching to do. Your method about copying one buffer over to another is good but you have to observe some caveats. What you may end up creating with your method is a ''race condition.'' That is, it may be possible that your ISR is busy sending out data from a buffer at the exact moment that you start copying a new one in and it sends half of the old one and half of the new one. One way to prevent this would be to only copy the buffer if the t_disabled bit is 1 (that is, the ISR has finished sending all the bytes in the last message). I guess as long as you're careful it will be fine. I just thought I'd mention this because race conditions can cause some of the most difficult to troubleshoot intermittent bugs in existence. Best Regards, Phaze4262011-05-17 03:00 AM
Thanks for the tip,
I allready did that, because as you mentioned, without waiting for t1_disabled every transmit overlaps with the previous one, and I got ab-normal printout. I have to say that the uPSD design for interrupts is just genius at its simplisity. Thank you.