home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- MEASURE.C: Remote Measurement Recorder using the C-51 COMPILER
-
- Copyright 1995 KEIL Software, Inc.
- ------------------------------------------------------------------------------*/
-
- code char menu[] =
- "\n"
- "+**************** REMOTE MEASUREMENT RECORDER *****************+\n"
- "| This program is a simple Measurement Recorder. It is based |\n"
- "| on the 80515 CPU and records the state of Port 4 and Port 5 |\n"
- "| and the voltage on the four analog inputs AN0 through AN3. |\n"
- "+ command -+ syntax -----+ function ---------------------------+\n"
- "| Read | R [n] | read <n> recorded measurements |\n"
- "| Display | D | display current measurement values |\n"
- "| Time | T hh:mm:ss | set time |\n"
- "| Interval | I mm:ss.ttt | set interval time |\n"
- "| Clear | C | clear measurement records |\n"
- "| Quit | Q | quit measurement recording |\n"
- "| Start | S | start measurement recording |\n"
- "+----------+-------------+-------------------------------------+\n";
-
- #include <stdio.h> /* standard I/O .h-file */
- #include <stdlib.h> /* standard library .h-file */
- #include <reg515.h> /* special function register 80515 */
- #include <ctype.h> /* character functions */
-
- struct clock { /* structure of the clock record */
- unsigned char hour; /* hour */
- unsigned char min; /* minute */
- unsigned char sec; /* second */
- unsigned int msec; /* milliseconds */
- };
-
- struct mrec { /* structure for measurement records */
- struct clock time; /* time of measurement */
- unsigned char port4; /* state of port 4 */
- unsigned char port5; /* state of port 5 */
- unsigned char analog [4]; /* voltage on analog Pins AN0 .. AN3 */
- };
-
- struct interval { /* structure for interval record */
- unsigned char min; /* minute */
- unsigned char sec; /* second */
- unsigned int msec; /* milli second */
- };
-
- extern getline (char idata *line, char n); /* external functions: input line */
- extern measure_display (struct mrec disp); /* display measurements */
- extern set_time (char * buffer); /* set current time */
- extern set_interval (char * buffer); /* set interval time */
-
- struct interval setinterval; /* interval setting values */
- struct interval interval; /* interval counter */
-
- unsigned char intcycle = 0; /* Interrupt cycle counter */
-
- bit measurement_interval = 0; /* measurement interval over */
- bit mdisplay = 0; /* measurement display requested */
- bit startflag = 0; /* start measurement recording */
-
- struct mrec current; /* current measurements */
-
- #define XRAM 8192 /* size of XDATA RAM is 8 KBytes */
- #define SCNT XRAM / sizeof (current) /* number of records in XDATA RAM */
-
- xdata struct mrec save_record [SCNT]; /* buffer for measurements */
- unsigned int sindex; /* save index */
- unsigned int savefirst; /* save first index */
-
- code char ERROR [] = "\n*** ERROR: %s\n"; /* ERROR message string in code */
-
- #define PERIOD -250 /* 250 usec interrupt period */
- #define WRONGINDEX 0xffff /* error signal for wrong index */
-
-
- /*
- * The following function is called from the interrupt service routine. This
- * means that the code must be generated in the same Register Bank as the
- * interrupt service function.
- */
- #pragma REGISTERBANK (1) /* use Register Bank 1 for coding */
-
- /******************************************************************************/
- /* Save current measurements in save_record */
- /******************************************************************************/
- void save_current_measurements () {
- save_record[sindex++] = current; /* copy current measurements */
- if (sindex == SCNT) sindex = 0; /* check bounds of sindex */
- if (sindex == savefirst) { /* check circular buffer limits*/
- if (++savefirst == SCNT) savefirst = 0; /* check bounds of savefirst */
- }
- }
-
-
- /******************************************************************************/
- /* Timer 0 interrupt service function */
- /* executes each 250us @ 12 MHz Crystal Clock */
- /******************************************************************************/
- timer0() interrupt 1 using 1 { /* Int Vector at 000BH, Reg Bank 1 */
-
- unsigned char i;
-
- if (measurement_interval) { /* measurement done ? */
- save_current_measurements (); /* yes -> save measurements */
- measurement_interval = 0; /* Save measurements done */
- }
-
- if (++intcycle == 4) { /* 1 msec = 4 * 250 usec cycle */
- intcycle = 0;
- /* check if interval is over */
- if (interval.min == 0 &&
- interval.sec == 0 &&
- interval.msec == 0 ) {
- interval = setinterval; /* set interval time again */
- measurement_interval = startflag; /* determine measurement flag */
- }
- else { /* update interval time */
- if (interval.msec-- == 0) { /* calculate millisecond */
- interval.msec = 999;
- if (interval.sec-- == 0) { /* calculate second */
- interval.sec = 59;
- interval.min--; /* calculate minute */
- }
- }
- }
- /* update current time */
- if (++current.time.msec == 1000) { /* update millisecond cnt */
- current.time.msec = 0;
-
- if (++current.time.sec == 60) { /* update second counter */
- current.time.sec = 0;
-
- if (++current.time.min == 60) { /* update minute counter */
- current.time.min = 0;
-
- if (++current.time.hour == 24) { /* update hour counter */
- current.time.hour = 0;
- }
- }
- }
- } /* end of if( ++current.time.msec... */
-
- if (measurement_interval || mdisplay) { /* process measurement */
- current.port4 = P4; /* read port 4 */
- current.port5 = P5; /* read port 5 */
- for (i = 0; i != 4; i++) { /* loop for 4 A/D inputs */
- ADCON &= 0xF8; /* strip off prev A/D selection*/
- ADCON |= i; /* select A/D input */
- DAPR = 0; /* start conversion */
- while (BSY); /* wait for A/D result */
- current.analog[i] = ADDAT; /* result of A/D process */
- }
- mdisplay = 0; /* mdisplay = 0 for ready sig. */
- }
- }
- }
-
-
- /*
- * The following functions are called from the main routine. Therefore
- * Register Bank 0 must be used when coding these functions.
- */
-
- #pragma REGISTERBANK (0) /* use Register Bank 0 for coding */
- /******************************************************************************/
- /* Calculate first Read Index */
- /******************************************************************************/
- unsigned int read_index (char *buffer) {
- int index = 0;
- unsigned char args;
-
- if (setinterval.min == 0 && /* check if setinterval is */
- setinterval.sec == 0 && /* below 1 second and */
- setinterval.msec < 999 && /* measurements are collected */
- startflag ) {
- printf (ERROR, "QUIT MEASUREMENTS BEFORE READ");
- return (WRONGINDEX); /* no display on the fly if */
- } /* interval time < 1 second */
- args = sscanf (buffer, "%d", &index); /* scan input for read count */
- if (args == 0 || index == 0 || args == EOF) index = SCNT-1;
- index = sindex - index; /* calculate first read index */
- if (index < 0) index += SCNT; /* from read count */
- return (index);
- }
-
-
- /******************************************************************************/
- /* Clear Measurement Records */
- /******************************************************************************/
- void clear_records (void) {
- unsigned int idx; /* index for loop */
-
- startflag = 0; /* stop measurement collecting */
- sindex = savefirst = 0; /* reset circular buffer index */
- for (idx = 0; idx != SCNT; idx++) { /* mark all records unused */
- save_record[idx].time.hour = 0xff; /* unused flag: hour = 0xff */
- }
- }
-
-
- /******************************************************************************/
- /*************************** MAIN PROGRAM ***************************/
- /******************************************************************************/
- void main ( void ) { /* main entry for program */
- idata char cmdbuf [15]; /* command input buffer */
- unsigned char i; /* index for command buffer */
- unsigned int idx; /* index for circular buffer */
-
- /* initialize the serial interface */
- SCON = 0x5A; /* initialize UART to mode 1 */
- BD = 1; /* internal Baudrate Generator */
- PCON |= 0x80; /* set to 9600 Baud @ 12 MHz */
-
- /* setup the timer 0 interrupt */
- TH0 = PERIOD; /* set timer period */
- TL0 = PERIOD;
- TMOD = TMOD | 0x02; /* select mode 2 */
- TR0 = 1; /* start timer 0 */
- ET0 = 1; /* enable timer 0 interrupt */
- EAL = 1; /* global interrupt enable */
-
- clear_records (); /* initialize circular buffer */
- printf ( menu ); /* display command menu */
- while (1) { /* loop forever */
- printf ("\nCommand: ");
- getline (&cmdbuf[0], sizeof (cmdbuf)); /* input command line */
-
- for (i = 0; cmdbuf[i] != 0; i++) { /* convert to upper characters */
- cmdbuf[i] = toupper(cmdbuf[i]);
- }
-
- for (i = 0; cmdbuf[i] == ' '; i++); /* skip blanks */
-
- switch (cmdbuf[i]) { /* proceed to command function */
-
- case 'R': /* Read circular Buffer */
- if ((idx = read_index (&cmdbuf[i+1])) == WRONGINDEX) break;
- while (idx != sindex) { /* check end of table */
- if (RI) { /* check serial interface */
- if (_getkey() == 0x1B) break; /* for escape character */
- }
- if (save_record[idx].time.hour != 0xff) {
- measure_display (save_record[idx]); /* display record */
- printf ("\n");
- }
- if (++idx == SCNT) idx = 0; /* next circular buffer entry */
- }
- break;
-
- case 'T': /* Enter Current Time */
- set_time (&cmdbuf[i+1]);
- break;
-
- case 'I': /* Enter Interval Time */
- set_interval (&cmdbuf[i+1]);
- break;
-
- case 'D': /* Display Command */
- printf ("\nDisplay current Measurements: (ESC to abort)\n");
- do {
- while (! RI) { /* check serial interface */
- mdisplay = 1; /* request measurement */
- while (mdisplay); /* wait for measurement */
- measure_display (current); /* display values */
- }
- } while (_getkey () != 0x1b); /* escape terminates command */
- printf ("\n\n");
- break;
-
- case 'S': /* Start Command */
- printf ("\nStart Measurement Recording\n");
- startflag = 1;
- break;
-
- case 'Q': /* Quit Command */
- printf ("\nQuit Measurement Recording\n");
- startflag = 0;
- break;
-
- case 'C': /* Clear Command */
- printf ("\nClear Measurement Records\n");
- clear_records ();
- break;
-
- default: /* Error Handling */
- printf (ERROR, "UNKNOWN COMMAND");
- printf (menu); /* display command menu */
- break;
- }
- }
- }
-
-