home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / HITECH-C / Z8051H83.EXE / FEAT8051.C < prev    next >
C/C++ Source or Header  |  1993-05-21  |  5KB  |  163 lines

  1. #include    <intrpt.h>
  2. #include    <8051.h>
  3.  
  4. /*
  5.  *    This source file demonstrates some of the special features
  6.  *    of the HI-TECH 8051 C Cross Compiler.  This program should
  7.  *    be compiled with 8051 code generation selected.
  8.  *
  9.  *    To generate the best possible code for this program, select
  10.  *    "Full Optimization" and "Speed Optimization" from the "Optimization"
  11.  *    menu and "Small Model" from the "Options" menu.
  12.  *
  13.  *    HI-TECH C has a number of features designed to make programming
  14.  *    embedded processors simpler and more efficient, these include:
  15.  *
  16.  *    interrupt functions: interrupt handlers may be written entirely
  17.  *                 in C (no messy assembler code required).
  18.  *                 The 8051 cross compiler also allows functions
  19.  *                 to be declared as "bank2 interrupt" or
  20.  *                 "bank3 interrupt"
  21.  *
  22.  *                 "bank2" and "bank3" interrupt functions
  23.  *                 preserve the general registers by switching
  24.  *                 register banks to bank 2 or 3 respectively,
  25.  *                 thereby saving the overhead of pushing the
  26.  *                 registers onto the stack.
  27.  *
  28.  *    absolute variables:  variables of any type (even complex
  29.  *                 structures and arrays) can be placed at
  30.  *                 any absolute address in memory - great
  31.  *                 for handling memory mapped devices and 8051
  32.  *                 special function registers.  All of the standard
  33.  *                 8051 special function registers are declared
  34.  *                 in the header <8051.h>.
  35.  *
  36.  *    in-line assembler:   assembler code can be place in line.  This
  37.  *                 is useful for accessing special instructions.
  38.  *
  39.  *    bit variables:         The 8051 bit addressable locations can be
  40.  *                 accessed efficiently by declaring variables
  41.  *                 to be of type "bit".  Compiler generated code
  42.  *                 manipulates "bit" variables using the 8051's
  43.  *                 efficient set of bit handling instructions.
  44.  *
  45.  *    register arguments:  some function arguments are passed in
  46.  *                 the R4 and R5 registers.  Register based
  47.  *                 argument passing is much faster and more
  48.  *                 compact than stack based passing.
  49.  */
  50.  
  51. #ifndef    i8051
  52. #error    This program should be compiled to 8051 code
  53. #endif
  54.  
  55. volatile far unsigned char    PIA_STATUS @ 0xFF80;    /* mem mapped PIA */
  56. volatile far unsigned char    PIA_BUFFER @ 0xFF81;    /* at FF80 - FF81 */
  57.  
  58. unsigned char    rxbuf[16];            /* 16 byte circular buffer */
  59. unsigned char    ri_ptr, ro_ptr;            /* head, tail pointers */
  60.  
  61. /*
  62.  *    rx_intr handles receive interrupts from the on board serial port
  63.  */
  64.  
  65. bank2 interrupt void
  66. rx_intr(void)
  67. {
  68.     rxbuf[ri_ptr++] = SBUF;
  69.     RI = 0;                /* clear interrupt state */
  70.     ri_ptr &= 0x0F;
  71.     if (ro_ptr == ri_ptr)        /* buffer overflow ? */
  72.         ri_ptr = (ri_ptr - 1) & 0x0F;    /* discard last byte received */
  73. }
  74.  
  75. /*
  76.  *    serial_char_avail: returns 1 if a char is available, 0 otherwise
  77.  */
  78.  
  79. unsigned char
  80. serial_char_avail(void)
  81. {
  82.     return (ri_ptr != ro_ptr);
  83. }
  84.  
  85. /*
  86.  *    serial_get_char: returns one char from the tail of the circular
  87.  *                  buffer.  Assumes that a char is available.
  88.  */
  89.  
  90. unsigned char
  91. serial_get_char(void)
  92. {
  93.     unsigned char    ch;
  94.  
  95.     di();
  96.     ch = rxbuf[ro_ptr++];
  97.     ro_ptr &= 0x0F;
  98.     ei();
  99.     return ch;
  100. }
  101.  
  102. /*
  103.  *    Transmit a character via the memory mapped PIA
  104.  *    bit 0 of STATUS register indicates it is ready to accept data
  105.  *
  106.  *    Note: register based argument passing is used with this
  107.  *    function.  "ch" will be passed in the R5 register.  If FULL
  108.  *    optimization is performed, "ch" probably won't ever be stored
  109.  *    to a stack location.
  110.  */
  111.  
  112. void
  113. pia_send(unsigned char ch)
  114. {
  115.     while (!(PIA_STATUS & 1))
  116.         continue;
  117.     PIA_BUFFER = ch;
  118. }
  119.  
  120. /*
  121.  *    Initialize the serial port and PIA - demo code only, not intended to be
  122.  *    an accurate example of 8051 programming
  123.  *
  124.  *    Notes on code generated:
  125.  *        1.    Note the use of SETB and CLRB instructions when
  126.  *            manipulating bit addressible locations like EA and ES
  127.  *
  128.  *        2.    Note the efficient code generated when manipulating
  129.  *            SFRs with statements like TMOD &= 0x0F;
  130.  *
  131.  *        3.    The serial port initialization code below is "real"
  132.  *            and was taken from the source code for the 8051
  133.  *            "Lucifer" monitor (supplied with the compiler).
  134.  */
  135.  
  136. void
  137. device_inits(void)
  138. {
  139.     EA = 0;            /* interrupts of while programming devices */
  140.     set_vector(SINT, rx_intr);
  141.     SCON = 0x52;        /* mode 1, receiver enable */
  142.     TMOD &= 0x0F;
  143.     TMOD |= 0x20;        /* timer 1 auto-reload mode */
  144.     PCON |= 0x80;        /* set SMOD: double baud rate */
  145.     TL1 = -3;
  146.     TH1 = -3;        /* about 19200 baud at 10.695 MHz */
  147.     TR1 = 1;        /* enable timer 1 */
  148.     PIA_STATUS = 0x80;    /* reset PIA */
  149.     PIA_STATUS = 0x40;    /* mode 2: bidirectional, interrupts off */
  150.     ES = 1;            /* serial interrupts on */
  151.     EA = 1;            /* global interrupt enable */
  152. }
  153.  
  154. main()
  155. {
  156.     device_inits();
  157.     for (;;) {
  158.         if (serial_char_avail())
  159.             pia_send(serial_get_char());
  160.         /* other processing */
  161.     }
  162. }
  163.