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 >
Wrap
C/C++ Source or Header
|
1993-05-21
|
5KB
|
163 lines
#include <intrpt.h>
#include <8051.h>
/*
* This source file demonstrates some of the special features
* of the HI-TECH 8051 C Cross Compiler. This program should
* be compiled with 8051 code generation selected.
*
* To generate the best possible code for this program, select
* "Full Optimization" and "Speed Optimization" from the "Optimization"
* menu and "Small Model" from the "Options" menu.
*
* HI-TECH C has a number of features designed to make programming
* embedded processors simpler and more efficient, these include:
*
* interrupt functions: interrupt handlers may be written entirely
* in C (no messy assembler code required).
* The 8051 cross compiler also allows functions
* to be declared as "bank2 interrupt" or
* "bank3 interrupt"
*
* "bank2" and "bank3" interrupt functions
* preserve the general registers by switching
* register banks to bank 2 or 3 respectively,
* thereby saving the overhead of pushing the
* registers onto the stack.
*
* absolute variables: variables of any type (even complex
* structures and arrays) can be placed at
* any absolute address in memory - great
* for handling memory mapped devices and 8051
* special function registers. All of the standard
* 8051 special function registers are declared
* in the header <8051.h>.
*
* in-line assembler: assembler code can be place in line. This
* is useful for accessing special instructions.
*
* bit variables: The 8051 bit addressable locations can be
* accessed efficiently by declaring variables
* to be of type "bit". Compiler generated code
* manipulates "bit" variables using the 8051's
* efficient set of bit handling instructions.
*
* register arguments: some function arguments are passed in
* the R4 and R5 registers. Register based
* argument passing is much faster and more
* compact than stack based passing.
*/
#ifndef i8051
#error This program should be compiled to 8051 code
#endif
volatile far unsigned char PIA_STATUS @ 0xFF80; /* mem mapped PIA */
volatile far unsigned char PIA_BUFFER @ 0xFF81; /* at FF80 - FF81 */
unsigned char rxbuf[16]; /* 16 byte circular buffer */
unsigned char ri_ptr, ro_ptr; /* head, tail pointers */
/*
* rx_intr handles receive interrupts from the on board serial port
*/
bank2 interrupt void
rx_intr(void)
{
rxbuf[ri_ptr++] = SBUF;
RI = 0; /* clear interrupt state */
ri_ptr &= 0x0F;
if (ro_ptr == ri_ptr) /* buffer overflow ? */
ri_ptr = (ri_ptr - 1) & 0x0F; /* discard last byte received */
}
/*
* serial_char_avail: returns 1 if a char is available, 0 otherwise
*/
unsigned char
serial_char_avail(void)
{
return (ri_ptr != ro_ptr);
}
/*
* serial_get_char: returns one char from the tail of the circular
* buffer. Assumes that a char is available.
*/
unsigned char
serial_get_char(void)
{
unsigned char ch;
di();
ch = rxbuf[ro_ptr++];
ro_ptr &= 0x0F;
ei();
return ch;
}
/*
* Transmit a character via the memory mapped PIA
* bit 0 of STATUS register indicates it is ready to accept data
*
* Note: register based argument passing is used with this
* function. "ch" will be passed in the R5 register. If FULL
* optimization is performed, "ch" probably won't ever be stored
* to a stack location.
*/
void
pia_send(unsigned char ch)
{
while (!(PIA_STATUS & 1))
continue;
PIA_BUFFER = ch;
}
/*
* Initialize the serial port and PIA - demo code only, not intended to be
* an accurate example of 8051 programming
*
* Notes on code generated:
* 1. Note the use of SETB and CLRB instructions when
* manipulating bit addressible locations like EA and ES
*
* 2. Note the efficient code generated when manipulating
* SFRs with statements like TMOD &= 0x0F;
*
* 3. The serial port initialization code below is "real"
* and was taken from the source code for the 8051
* "Lucifer" monitor (supplied with the compiler).
*/
void
device_inits(void)
{
EA = 0; /* interrupts of while programming devices */
set_vector(SINT, rx_intr);
SCON = 0x52; /* mode 1, receiver enable */
TMOD &= 0x0F;
TMOD |= 0x20; /* timer 1 auto-reload mode */
PCON |= 0x80; /* set SMOD: double baud rate */
TL1 = -3;
TH1 = -3; /* about 19200 baud at 10.695 MHz */
TR1 = 1; /* enable timer 1 */
PIA_STATUS = 0x80; /* reset PIA */
PIA_STATUS = 0x40; /* mode 2: bidirectional, interrupts off */
ES = 1; /* serial interrupts on */
EA = 1; /* global interrupt enable */
}
main()
{
device_inits();
for (;;) {
if (serial_char_avail())
pia_send(serial_get_char());
/* other processing */
}
}