home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 September / pcwk_09_96.iso / demo / wgelectr / pk51demo / files.2 / EXAMPLES / TRAFFIC / SERIAL.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  7KB  |  138 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*       SERIAL.C:  Interrupt Controlled Serial Interface for RTX-51 tiny     */
  4. /*                                                                            */
  5. /******************************************************************************/
  6.  
  7.  
  8. #include <reg52.h>                    /* special function register 8052       */
  9. #include <rtx51tny.h>                 /* RTX-51 tiny functions & defines      */
  10.  
  11. #define  OLEN  8                      /* size of serial transmission buffer   */
  12. unsigned char  ostart;                /* transmission buffer start index      */
  13. unsigned char  oend;                  /* transmission buffer end index        */
  14. idata    char  outbuf[OLEN];          /* storage for transmission buffer      */
  15. unsigned char  otask = 0xff;          /* task number of output task           */
  16.  
  17. #define  ILEN  8                      /* size of serial receiving buffer      */
  18. unsigned char  istart;                /* receiving buffer start index         */
  19. unsigned char  iend;                  /* receiving buffer end index           */
  20. idata    char  inbuf[ILEN];           /* storage for receiving buffer         */
  21. unsigned char  itask = 0xff;          /* task number of output task           */
  22.  
  23. #define   CTRL_Q  0x11                /* Control+Q character code             */
  24. #define   CTRL_S  0x13                /* Control+S character code             */
  25.  
  26. bit   sendfull;                       /* flag: marks transmit buffer full     */
  27. bit   sendactive;                     /* flag: marks transmitter active       */
  28. bit   sendstop;                       /* flag: marks XOFF character           */
  29.  
  30. /******************************************************************************/
  31. /*       putbuf:  write a character to SBUF or transmission buffer            */
  32. /******************************************************************************/
  33. putbuf (char c)  {
  34.   if (!sendfull)  {                   /* transmit only if buffer not full     */
  35.     if (!sendactive && !sendstop)  {  /* if transmitter not active:           */
  36.       sendactive = 1;                 /* transfer the first character direct  */
  37.       SBUF = c;                       /* to SBUF to start transmission        */
  38.     }
  39.     else  {                           /* otherwize:                           */
  40.       outbuf[oend++ & (OLEN-1)] = c;  /* transfer char to transmission buffer */
  41.       if (((oend ^ ostart) & (OLEN-1)) == 0)  sendfull = 1;
  42.     }                                 /* set flag if buffer is full           */
  43.   }
  44. }
  45.  
  46.  
  47. /******************************************************************************/
  48. /*       putchar:  interrupt controlled putchar function                      */
  49. /******************************************************************************/
  50. char putchar (char c)  {
  51.   if (c == '\n')  {                   /* expand new line character:           */
  52.     while (sendfull)  {               /* wait for transmission buffer empty   */
  53.       otask = os_running_task_id ();  /* set output task number               */
  54.       os_wait (K_SIG, 0, 0);          /* RTX-51 call: wait for signal         */
  55.       otask = 0xff;                   /* clear output task number             */
  56.     }
  57.     putbuf (0x0D);                    /* send CR before LF for <new line>     */
  58.   }
  59.   while (sendfull)  {                 /* wait for transmission buffer empty   */
  60.     otask = os_running_task_id ();    /* set output task number               */
  61.     os_wait (K_SIG, 0, 0);            /* RTX-51 call: wait for signal         */
  62.     otask = 0xff;                     /* clear output task number             */
  63.   }
  64.   putbuf (c);                         /* send character                       */
  65.   return (c);                         /* return character: ANSI requirement   */
  66. }
  67.  
  68.  
  69. /******************************************************************************/
  70. /*       _getkey:  interrupt controlled _getkey                               */
  71. /******************************************************************************/
  72. char _getkey (void)  {
  73.   while  (iend == istart)  {
  74.     itask = os_running_task_id ();    /* set input task number                */
  75.     os_wait (K_SIG, 0, 0);            /* RTX-51 call: wait for signal         */
  76.     itask = 0xff;                     /* clear input task number              */
  77.   }
  78.   return (inbuf[istart++ & (ILEN-1)]);
  79. }
  80.  
  81.  
  82. /******************************************************************************/
  83. /*       serial:  serial receiver / transmitter interrupt                     */
  84. /******************************************************************************/
  85. serial () interrupt 4 using 2  {     /* use registerbank 2 for interrupt      */
  86.   unsigned char c;
  87.   bit   start_trans = 0;
  88.  
  89.   if (RI)  {                         /* if receiver interrupt                 */
  90.     c = SBUF;                        /* read character                        */
  91.     RI = 0;                          /* clear interrupt request flag          */
  92.     switch (c)  {                    /* process character                     */
  93.       case CTRL_S:
  94.         sendstop = 1;                /* if Control+S stop transmission        */
  95.         break;
  96.  
  97.       case CTRL_Q:
  98.         start_trans = sendstop;      /* if Control+Q start transmission       */
  99.         sendstop = 0;
  100.         break;
  101.  
  102.       default:                       /* read all other characters into inbuf  */
  103.         if (istart + ILEN != iend)  {
  104.           inbuf[iend++ & (ILEN-1)] = c;
  105.         }
  106.                                      /* if task waiting: signal ready         */
  107.         if (itask != 0xFF) isr_send_signal (itask);
  108.         break;
  109.     }
  110.   }
  111.  
  112.   if (TI || start_trans)  {          /* if transmitter interrupt              */
  113.     TI = 0;                          /* clear interrupt request flag          */
  114.     if (ostart != oend)  {           /* if characters in buffer and           */
  115.       if (!sendstop)  {              /* if not Control+S received             */
  116.         SBUF = outbuf[ostart++ & (OLEN-1)];      /* transmit character        */
  117.         sendfull = 0;                /* clear 'sendfull' flag                 */
  118.                                      /* if task waiting: signal ready         */
  119.         if (otask != 0xFF)  isr_send_signal (otask);
  120.       }
  121.     }
  122.     else sendactive = 0;             /* if all transmitted clear 'sendactive' */
  123.   }
  124.  
  125. }
  126.  
  127.  
  128. /******************************************************************************/
  129. /*       serial_init: initialize serial interface                             */
  130. /******************************************************************************/
  131. serial_init ()  {
  132.   SCON  = 0x50;                      /* mode 1: 8-bit UART, enable receiver   */
  133.   TMOD |= 0x20;                      /* timer 1 mode 2: 8-Bit reload          */
  134.   TH1   = 0xf3;                      /* reload value 2400 baud                */
  135.   TR1   = 1;                         /* timer 1 run                           */
  136.   ES    = 1;                         /* enable serial port interrupt          */
  137. }
  138.