Lawrence Lile wrote: > So here is the architecture question: To interrupt or poll? Put the > RX line and interrupt on PortB,0, and use the "external interrupt"? > Move it all back to a hardware UART, and use that as an interrupt > source? Or poll it all the time with kbhit() ? How do other people > approach this? First, I don't use a compiler, so I don't have some of these problems. Most of the time I use interrupt driven UART I/O with software input and output FIFOs. The code has been used many times and automatically configures itself to the target chip and oscillator frequency. All I do is set the FIFO sizes and baud rate. This template code is QQQ_UART.ASPIC at http://www.embedinc.com/pic. Once a basic UART input routine exists, there are several options for reading the input stream. The code I referred to above sets a global flag bit whenever something is in the input FIFO. For simple input streams, I poll this in the main loop and jump to the event handler only if there is an input byte so that it is guaranteed not to wait. The next level up, which is the most common case for 16 family PICs, is an input stream processing module that implements a pseudo thread. The event handler gets envoked from the main event loop only when an input byte is available. The event handler reads the byte from the input FIFO and returns from the GETBYTE macro of the pseudo thread code. The next GETBYTE invocation causes a return to the main event loop. This structure can greatly simplify parsing an input stream because from the thread's point of view it goes and "gets" then next input byte when bytes are really coming at it. Once all the thread and event handling details have been written, the input stream handling code is easy to write and clean. A template for this is also available in the QQQ_CMD.ASPIC module from the same web page. You shouldn't need to mess with the thread handling stuff, just fill in your own stream parsing code. The next level up is a pseudo thread that gets run for a timeslice every time thru the main event loop. This has a generic YIELD macro where the return to the event loop is hidden from the pseudo thread. GETBYTE is a macro that checks the input FIFO flag and invokes YIELD in a loop until an input byte is available. This architecture is a little more complex, but allows the thread to wait on other events than just an input byte available. On the 18 family you can implement real threads that call a YIELD subroutine as apposed to invoking a YIELD macro. The main difference is that YIELD may be called nested at a lower level from the top event routine since the stack can be accessed and the appropriate save/restore performed when the thread is switched in and out. To minimize the stack storage space required, I have a configuration constant that says how many nested levels down the thread is allowed to call YIELD. So far I haven't attempted to deal with the data stack, so nothing may be left on the data stack when YIELD is called. On the 30 family full blown true threads (tasks) are easy since the stack is in regular data memory and is used for both data and return addresses. So far all my PIC 30 projects that performed UART I/O have used tasks. The code for managing tasks and performing task switching is very simple, due to the dsPIC's nice architecture. It is available in QQQ_TASK.DSPIC under the dsPIC Templates heading on the same web page. This was probably a lot more than you wanted to hear, but you asked. As you can probably gather, I've been down this road dozens of times before. ***************************************************************** Embed Inc, embedded system specialists in Littleton Massachusetts (978) 742-9014, http://www.embedinc.com -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics