General design question for PIC based hand held terminal

Thread Starter

dk-info

Joined Mar 9, 2009
8
I have a simple hand held serial terminal design using a PIC18F1330, a 4 x 20 LCD display and 4 buttons. This terminal will interface to a controller, set/display parameters and display status. I am using CCS C-compiler, taking advantage of the built in RS232 & LCD functions. Separately I can exercise each peripheral, now it is time to tie it all together. Typically my designs involved a "Super Loop " architecture:

while(forever) {
do_this();
do that();
} // end while(forever)

And I guess I could do this for my terminal, within the super loop polling for characters, button pushes, keeping a pile of global variables with the ensuing complex state maintenance. I would also like to keep track of linear time, to use for timeout periods.

I say to myself, "Self, you should use interrupts ". OK, it is straight forward to manage the serial events under interrupt control, and it is simple to have a periodic interrupt manage a variable that increments changes every 100 ms. Put these both together however, then salt the pile with some button polling, general state maintenance (the actual "stuff" the terminal needs to control) and the problem becomes evident.

I know of "time triggered" event processing, where there is only one interrupt, a periodic one, where events are polled and queued for processing in the super-loop. If I have a 1 kHz interrupt, what characters will be lost if I poll for serial? What happens if I have a 1 kHz interrupt and a serial interrupt? Intuition tells me I will have a collision. Do I maintain (during interrupt time now) collision detection states?

This "Simple" hand held terminal is becoming complex. I can throw together a pile of code that on the face of it works just fine individually, but when put together may fail in strange ways.

Is there a deterministic design method I can use to architect the software "by the numbers"? This not a homework assignment, but an attempt to move beyond hobby and into an engineered solution.

Cheers!
David
 

thatoneguy

Joined Feb 19, 2009
6,359
In the interrupt routine, test for which condition triggered the interrupt, act accordingly, clean up, continue.

I usually set a variable value in the interrupt routine, which is polled continually in the continual loop. If the variable was serial data received, then outside the interrupt, put that data to display, set variable to NULL. If variable is keypress code, put the data and formatting to Serial TX, set variable to NULL.

This is how Novo RTOS (RealTime Operating System) is often used, but not always.

ends up like this pseudocode:

Rich (BB code):
unsigned char serialdata;
unsigned char keydata;

void interrupt(void)
{
  if interrupt was from serial port
  {
       serialdata=SerialPort;
  }
  if interrupt was from keypress
  {
      keydata = keypress;
  }
  Enable interrupts / update clock / cleanup -- Keep it short and fast.
}

void main (void)
{

Set up interrupts, serial port, LCD, etc here..

while (1)
{
    if (serialdata) {
      LCD = serialdata;  //  Be Careful of Timing issues with LCD...  Gets ugly.
      serialdata = NULL;
    }
    
    if  (keydata) {
      SerialTX (keydata)
     keydata = NULL
   }
}
}
 
Last edited:
Top