sburrow wrote:
An idea I was thinking is that I could set up some type of an interrupt on the start bit.
That approach is workable if you're not concerned about being able to receive and transmit simultaneously (ie, Full Duplex). Maybe that capability isn't required.
But if Full Duplex
is the goal -- and assuming you only have one timer and interrupt line available (not one of each for transmit and one of each for receive) -- I'd suggest having a periodic interrupt that runs continuously whenever either or both task(s) is active. (For the sake of simpler code, it may even be reasonable to let the periodic interrupts continue even when neither the transmit task nor the receive task is active.)
You'll probably want the interrupts to occur at triple ( 3x ) the bit rate, because doing so allows you to start receiving a character at any time (meaning, on any given interrupt). Remember, you don't get to choose when an incoming character will arrive. You could be in the midst of transmitting a character, then suddenly need to also start
receiving a character. And of course it's unlikely that the bit-clock of the incoming character will be time-aligned with that of the outgoing character. But having interrupts at a 3x rate means the receive and transmit tasks can be phase shifted by zero, by 1/3, or by 2/3 of a bit-time relative to one another.
So! With the scheme I propose, if there's a character in the process of being transmitted then the Interrupt Service Routine will, on every third interrupt, shift out a bit onto the TxD output. And, if there's a character in the process of being received then the ISR will, on every third interrupt, shift in a bit from the RxD input.
To minimize the performance impact, the ISR needs to do the absolute minimum then exit as soon as possible. (After all, there'll be a foreground task that can manage the big picture.) One way to keep the ISR fast is to have it begin with an indirect jump (or, use self-modifying code) that gets updated according to what's going on. This'll be faster than having the ISR read various activity status bits then do conditional branches.
-- Jeff
Edits: improved explanation, and this PS. Further edit: fix diagram
Here's a diagram to explain the choice of a 3x interrupt rate, as opposed to 2x or 4x or any other number.
Attachment:
3x timing for asynch.png [ 3.38 KiB | Viewed 5667 times ]
The vertical red lines indicate interrupts, and sooner or later the incoming character will be detected. This entails a degree of variability, and the upper and lower depictions of the incoming character illustrate the boundaries of that variability.
At "B," the Start Bit is detected. Then at "C" a repetitive pattern begins. There'll be an interrupt that samples RxD, one that does nothing, another that does nothing, then the pattern repeats until all bits have been received. You'll notice that the "sample RxD" interrupts remain well centered within the bit-time (between 33% and 66%), as desired.