Category : Assembly Language Source Code
Archive   : SERIAL51.ZIP
Filename : SERIAL.C

 
Output of file : SERIAL.C contained in archive : SERIAL51.ZIP

/****************************************************************************/
/* */
/* MODULE NAME = Serial.c */
/* COMPONENT NAME = Serial.c */
/* */
/* DESCRIPTIVE NAME = Acorn Replacement Keypad Control Program */
/* */
/* COPYRIGHT = Public Domain */
/* */
/* Compiler = Franklin C Vers. 2.25 */
/* STATUS = Release 1 Version 1 */
/* */
/* FUNCTIONS = */
/* */
/* COMPILER OPTIONS = LARGE */
/* LINKER OPTIONS = XDATA (1800H) Note: for 8k DS5000 */
/* */
/* Credits: Derived from SKEL8051.ASM on CCI BBS - Thanks whoever */
/* */
/* */
/* CHANGE ACTIVITY = */
/* DATE |LEVEL |PROGRAMMER|DESCRIPTION */
/* ----------+---------+----------+--------------------------------------- */
/* 08 Aug 92 | 1.0 | T. Sare | First Version */
/* | | | */
/* */
/****************************************************************************/
/* Change version number here only */
unsigned char *Version_num = " Vers. 1.0 ";


#include /* define DS5000-8051 registers */


#define UCHAR unsigned char
#define UINT unsigned int
#define ULONG unsigned long



#define TRUE 1
#define FALSE 0
#define ON 1
#define OFF 0

#define MAXQUEUE 16 /* do not expand queue or rollover */
#define MODQUEUE 0x0f /* will not work !!! */
#define MAXMILLI 1000
#define MAXSEC 60

#define WATCHDOG_ON TA=0xAA;TA=0x55;PCON |= 0x04 /* enable watchdog */
#define WATCHDOG_OFF TA=0xAA;TA=0x55;PCON &= 0xFB /* disable watchdog */
#define WATCHDOG_RST TA=0xAA;TA=0x55;RWT=1 /* Reset Watch Dog timer */

#define POWER_FAIL_EN PCON |= 0x08 /* enable Power Fail int */
#define STOP_MICRO TA=0xAA;TA=0x55;PCON |= 0x02 /* Stop processor */


#define TIMER0_HIGH 0xFC /* Timer 0 is set for 1 mSec */
#define TIMER0_LOW 0x66


/* Protos */

bit receive_c(UCHAR *c);
bit send_c(UCHAR c);

void main(void);
void delay(unsigned int delaytime);

/* Global data */


typedef struct QUEUE
{
UCHAR head;
UCHAR tail;
UCHAR Queue[MAXQUEUE];
}QUEUE;

data QUEUE Transmit, Receive;
data QUEUE *RX,*TX;
data UCHAR i;


/* Global inits */

data UINT millisec; /* millisec counter for delays */
data UCHAR seconds;
bit success;
bit txgoing; /* user flag for TX routines */



/**************************************/
/* Timer 0 interrupt service function */
/**************************************/

/* executes once timer 0 overflow */
/* maintains high part of usec counter */

timer0() interrupt 1 using 2
{ /* Use Register bank 2 */

EA = OFF; /* NO INTS */
millisec++; /* increment on timer overflow */
if (millisec == MAXMILLI)
{ /* crude clock for timer functions */
seconds = (seconds + 1) % MAXSEC;
millisec = 0;
}
TL0 = TIMER0_LOW; /* Reload Low byte Timer 0 */
TH0 = TIMER0_HIGH; /* Reload High byte Timer 0 */
EA = ON;
}

serial() interrupt 4 using 3
{ /* Service the serial ports */
/* Use Register bank 3 */

ES = OFF; /* disable ints */
if (TI)
{ /* we have outgoing serial data */
TI = OFF; /* clear it */
txgoing = OFF; /* send in progress */
if (TX->head != TX->tail)
{ /* Send next char */
SBUF = TX->Queue[TX->head];
TX->head = (++TX->head) & MODQUEUE;
}
}
else
{ /* we have receive char */
RI = OFF; /* clear receive int bit */
if ( ( (RX->tail+1) & MODQUEUE) != RX->head)
{
RX->Queue[RX->tail] = SBUF; /* get the char */
RX->tail = (++RX->tail) & MODQUEUE; /* increment tail */
}
}
ES = ON; /* enable ints */
}


power_fail() interrupt 5 /* Interrupt Vector 0x2B - DS5000 Only */
{ /* Shut down and lockup */
WATCHDOG_OFF;
T1 = ON; /* the light may be on */
STOP_MICRO; /* Reset the only way to restart!! */
}



void main (void)
{ /* main program */


UCHAR rcvchar;

POWER_FAIL_EN; /* enable Power Fail int */
WATCHDOG_OFF;
T1 = 0; /* LED Off */
/* setup variable data */
millisec = 0l; /* Clear counter */
RX = &Receive; /* init queue pointers */
TX = &Transmit;
RX->head = RX->tail = 0;
TX->head = TX->tail = 0;
txgoing = OFF; /* clear send in progress */

SCON = 0xd2; /* SCON */ /* setup serial port = Mode 3 */
TMOD = 0x20; /* TMOD */ /* hardware (1200 BAUD @11.059 MHz) */
TH1 = 0xe8; /* TH1 */ /* Timer 1 Baud Rate Value */
TR1 = ON; /* enable timer */
ES = ON; /* enable serial interrupt */

/* setup timer 0 interrupt */
TMOD = TMOD | 0x01; /* select mode 1 */
TL0 = TIMER0_LOW; /* Set Low byte Timer 0 */
TH0 = TIMER0_HIGH; /* Set high byte Timer 0 for 1 msec */
ET0 = ON; /* enable timer 0 interrupt */

PS = ON; /* serial is highest priority */
EA = ON; /* global interrupt enable */
TR0 = ON; /* Start Timer 0 */

/* Start of main program loop */

while (TRUE)
{
WATCHDOG_RST; /* reset it. This line must come before */
/* WATCHDOG_ON; /* start watchdog. Enable after code is working!*/

T1 = ~T1; /* strobe led on T1 */

while ( !receive_c(&rcvchar) )
{
WATCHDOG_RST; /* whip the dog */
} /* endwhile */

/* do useful work hear */

send_c(rcvchar);
} /* endwhile */



} /* end main */

bit send_c(UCHAR c)
{ /* send a byte */

ES = OFF; /* disable ints */
success = FALSE;
if ( (TX->head != TX->tail) || txgoing )
{ /* add to queue */
if ( ((TX->tail+1) & MODQUEUE) != TX->head)
{ /* we got room to add */
TX->Queue[TX->tail] = c;
TX->tail = (TX->tail+1) & MODQUEUE;
success = TRUE;
}
}
else
{
SBUF = c;
txgoing = ON;
success = TRUE;
}
ES = ON; /* enable ints */
return (success);
}

bit receive_c(UCHAR *c)
{ /* get a char off the queue */

success = FALSE;
if ( RX->head != RX->tail)
{ /* we got a char on queue */
ES = OFF; /* disable ints */
*c = RX->Queue[RX->head];
RX->head = (++RX->head) & MODQUEUE;
ES = ON;
success = TRUE;
}
return(success);

}



void delay(unsigned int delaytime)
{ /* delay is in milliseconds, max delay is 65000 msec or 65 sec. */

data UINT alarm;

alarm = (millisec + delaytime) % MAXMILLI;
if (alarm < millisec)
{ /* we had rollover */
while (alarm < millisec)
{
WATCHDOG_RST;
continue;
}
}
else
{ /* normal mode */
while ( alarm > millisec)
{
WATCHDOG_RST;
continue;
}
}

} /* end delay */