cancel
Showing results for 
Search instead for 
Did you mean: 

transmit interrupt

jones2
Associate II
Posted on May 24, 2004 at 10:47

transmit interrupt

10 REPLIES 10
jones2
Associate II
Posted on May 17, 2011 at 12:00

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?

joseph2399
Associate II
Posted on May 17, 2011 at 12:00

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.

jones2
Associate II
Posted on May 17, 2011 at 12:00

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.
jdaniel
Associate II
Posted on May 17, 2011 at 12:00

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,

Phaze426
jones2
Associate II
Posted on May 17, 2011 at 12:00

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 ]

jdaniel
Associate II
Posted on May 17, 2011 at 12:00

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,

Phaze426
jones2
Associate II
Posted on May 17, 2011 at 12:00

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.
jdaniel
Associate II
Posted on May 17, 2011 at 12:00

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,

Phaze426
jones2
Associate II
Posted on May 17, 2011 at 12:00

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.