I just like to run my serial comm on an interrupt basis just for the simplicity and the cleanness of the code. Not to pimp someone else's stuff, but I found a very slick, efficient serial comm driver (interrupt based) from one of Freescale's distinguished competitors. I've attached it for those interested.
-Tomahawk
FC wrote:I have written a routine using SCI interrupts for transmit and recieve. Transmitting data using interrupts is way more complicated than polling. What is the advantage of interrupt driven transmit? Assuming the baud rate is fast, polling wait time will be less.
rocco wrote:
Hi, Ron:
I hear ya. I'm certainly not going to argue against simplicity.
I also hesitate to call the code I use a "Scheduler". It is really just a main loop that runs subroutines if the bit associated to that subroutine is set. There is simply a table of eight subroutine addresses, each associated with a bit in a page-zero byte. The priority is fixed, higher order bits being higher priority, because I simply scan left-to-right. An ISR or another routine can request a "task" to be run with a simple BSET instruction. If no bits are set, the loop executes a WAIT instruction.
I originally wrote this for the MC68701 twenty years ago, and have use it in every project since. It is an easy, debugged starting point for any project. It's also only 65 bytes of program space (including the dispatch table) and 1 byte of ram. I can post it, if anyone is interested.
Of course, as you pointed out, it forces most of my I/O routines to be interrupt driven. That's a price I no longer hesitate to pay.
Hi all,
On the recieve side you often use interrupts because as you can't really implement a byte by byte flow control, you MUST be ready to process each byte as they come or you will drop bytes.
However on the transmit side YOU are in control. This means that all is going to happen if you don't service it in time you will generate idle line condition for some time in between the bytes. So the only reason to NEED to use interrupts on Tx is to maximise the actual transmit rate in a system that would be otherwise to busy to achieve that using polling. The only other way to guarantee this is to go into a special poll loop until the message is sent however this would be a the expense of reponse time to other non-interrupt tasks.
David
Hello all,
Another instance where I have found interrupts useful for the sending of SCI data is where it is required to echo characters as they are received, when commands are entered via terminal emulation. If non-interrupt processes are lengthy, the character echo delay can be quite noticeable to the user. Of course it is possible to simply send the echo character within the SCI receive ISR, but this cannot be done if rudimentary editing of the entered command is required. For example, a destructive backspace would require three characters to be echoed (BS+space+BS).
For the receive ISR, some applications will require a FIFO (circular) buffer, perhaps with hardware and/or software flow control, and others may be able to use a simple line buffer, where processing of the line entry commences when CR is received. In the latter case, usually applicable to manual entry, flow control would not be necessary if a "prompt" character is sent when processing has been completed.
For a send ISR (when used) the complexity of a FIFO buffer shouldn't be necessary. A technique I have previously used is to set up a table to identify the start of the data for each message string that are mostly located in PROM or flash memory. However, I also allow for a small send buffer in RAM to be included in the table. It then becomes a relatively simple process (at least in assembler) to identify the required string by an index value, and then point to the start of the required null terminated data. The send ISR would then send the message, a single character for each interrupt, and then set a control flag when the null character is reached.
Regards,
Mac
Interrupt-driven RX is almost always a necessity (especially as the baud rate increases) unless your application spends most of its time waiting for commands from the SCI that return an acknowledgement to the other side before it sends the next command.
Interrupt-driven TX, on the other hand, is not a necessity (especially as the baud rate increases) but it provides smoother transmission between characters of a single message/packet/whatever and, depending on the size of queue used, can free up the main program immediately when arriving at 'print' statements. This may speed up the program's overall responsiveness and, if dealing with a user terminal, and have an RTOS it will appear more smoothly rather than irregular sized chunks of text arriving in bursts.
Now, if your baud rate is such that by the time you fetch the next byte the previous one has already been sent (or there about), then there is no significant advantage using interrupts. Polled mode may actually be a better choice since the coding is usually smaller (and easier).
Nevertheless, if you need an example for int-driven RX/TX have a look inside:
http://aspisys.com/asm11d84.zip
Look for file SCI_INT.MOD (68HC11 assembly language, very similar to HC08) from which you can derive the flowchart to use with your programming language (if not assembly). The key is turning off TX ints from within the interrupt handler when TX queue is empty so it stops firing, and turning them back on when any byte is added to the TX queue. See the code for more.