Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming Microcontrollers in C, 2-nd edit (Ted Van Sickle, 2001).pdf
Скачиваний:
306
Добавлен:
12.08.2013
Размер:
7.2 Mб
Скачать

370 Chapter 7 Advanced Topics

This function is tested with the following program:

#include <stdio.h>

void get(char *, int);

#define LENGTH 15

main()

{

char data[LENGTH];

get(data,LENGTH);

if(data[0]==’\0') printf(“Buffer overflow\n”);

else puts(data);

}

Listing 7-10: get() Test Routine

This program reads in a line of data and echoes the string to the computer screen. If the length of the input data is longer than the specified length, the Buffer overflow message is printed to the screen.

The Monitor Program

The next program to be written is the monitor routine. This function executes all of the time and receives data from the keyboard. It will interpret the entries and pass control to the appropriate function to execute. In building all of the functions, monitor(), printafter(), printout(), and reset(), there are a large number of constants and function prototypes that must be included in each function. All of these items will be collected together into a single header file to be included in each function. This header file is shown below as Listing 7-11. This file starts with the usual multiple inclusion protection. The code for this program will be tested completely on a DOS-based system before it is compiled for use for the final microcontroller. There are a couple of items needed for the DOS-based system that are not needed for the microcontroller. Therefore, the parameter DOS is defined at the beginning of the header

The Monitor Program 371

file and certain lines of the file will be included or excluded depending on the definition of this parameter.

It is intended to store the data in a linked list in memory. The linked list will have a node called an Entry. An Entry contains two characters that will be indices into the data array. The first member is the index to the data in the data array. The second member is an index to the next Entry for the next data entry. An array of 35 Entrys will be stored in EEPROM along with an array of 698 (=76835*2) chars to store the nonvolatile data. There are 768 bytes of EEPROM on the particular M68HC912B32 chip that we are using here.

A structure type named Epro is created to hold the collections of Entrys and the remaining data for the data storage area. This structure will be forced to the address 0xd00 at link time. It will also be identified as EEPROM so that assignments to this memory area will compile to storage to EEPROM rather than writes to normal data memory. The first three entries in the data[] array are devoted to special uses. data[0] contains the next open index into the data[] array, data[1] contains an index to the beginning of the list and data[2] contains the number of entries in the list. To simplify both the code writing and remembering of the uses of these memory locations, I used macros to define useful names for these locations. Also included here is an old favorite, the FOREVER loop.

#define DOS #ifndef PHONE_H #define PHONE_H

#ifdef DOS #include <stdio.h>

typedef unsigned int WORD; enum Bool{FALSE,TRUE}; #define FOREVER while(TRUE) #endif

#include <stdlib.h> #include <string.h>

typedef struct { unsigned dataindex;

372 Chapter 7 Advanced Topics

unsigned next;

}Entry;

 

#define ALEN

30

#define NLEN

16

#define DLEN

35

#define EEPROMLEN

768

#define DATAPROM

EEPROMLEN-DLEN*sizeof( Entry)

#define END

0xff

typedef struct {

Entry header[DLEN]; unsigned data[DATAPROM];

}Epro;

#define NEXT_OPEN epro->data[0] #define START_OF_LIST epro->data[1] #define LIST_ENTRIES epro->data[2]

void saveit(char *,char *,Epro *); void printout(Epro *);

void printafter(Epro *); void reset(Epro *);

int encode(char *,unsigned *,int); int decode(unsigned *,char *); void get(char *,int);

int numbdup(char * const, unsigned *, int); void putbcd(char *,char *);

#ifndef DOS

void inituart(void); void putchar(int); int getchar(void); void puts(char *); #endif

#endif

Listing 7-11: Phone Book Header File

The Monitor Program 373

The final portion of this header file is a collection of all of the function prototypes needed for this program. When this program is moved from the DOS-based system to the microcontroller-based system, it is necessary to remove the first line of the above header file. There are three functions found in the standard input/output library that will be rewritten for this program. These functions are inituart(), putchar(), getchar() and puts(). The function prototypes for these functions are included and will be discarded when the parameter DOS is not defined.

The monitor program is shown below in Listing 7-12. In the header file above, a structure was typedefed as an Epro. This structure is the size of the EEPROM on board the chip. An external instance of an Epro, named able, is created and it will be used as a destination for all of the nonvolatile stored data in the program.

Inside the main() program, two arrays are created: one array to store the name entered from the keyboard and the other to store the phone number entered from the keyboard. Also, the external structure will be passed around from function to function via a pointer. This pointer is created and initialized to the structure able. Also, if the parameter DOS is not defined, the function inituart() is executed to enable the use of the UART on the microcontroller when it is needed.

After this initialization is completed, control is passed into a FOREVER loop where it will remain so long as the computer continues to run. Within this loop, an input is read from the keyboard. It is assumed that the keyboard input will read in the data and return ASCII characters. If the system is a part of a telephone or a PDA, the input routine will have to read in the keyboard data and convert it to the correct ASCII value prior to its use in the following program. Therefore, getchar() in the following program can be a function that reads data from a serial port or some other program that will input the data from whatever keyboard is used with the system. Inside of the FOREVER loop, a character is read in and then it is tested in a switch()/case sequence. The current test values are ‘n’, ‘a’, ‘s’, and ‘r’. These inputs are commands that determine what the program will do:

Command

Action

n

Read in a number/name sequence, encode these

 

data and save them in the nonvolatile array.

374 Chapter 7 Advanced Topics

r

Reset the system and erase the EEPROM array

 

which destroys all stored information.

s

Display all stored data in sequence.

a

Display the next stored number and name.

The functions that perform these various operations are discussed in the following sections. All of the case choices merely call the required function with the exception of the ‘n’ command. The ‘n’ command calls the function get() twice to read in the number followed by the name. These data are stored in the designated arrays and the two arrays containing the data are passed to the function saveit() along with a pointer to the nonvolatile structure able. Otherwise, the program remains in the FOREVER loop, exiting the loop only to execute commands entered from the keyboard.

/* monitor.c is the initial program that is being developed to use on the HC12.The end product can be used as a part of a PDA or a telephone that requires that you enter names and phone numbers.These entries are to be saved in nonvolatile RAM such as flash or EEPROM, perhaps both. In order to save memory space, encoding of the stored data will be used. All numbers will be stored as BCD digits and letters will be stored as a Huffman code.It

is assumed that letter fields and number fields will not contain mixed data.

The code in this program is programmed for the DOS based system. No printf is used,

but other i/o functions are used as needed. It is assumed now that any input will be

received as serial data from a serial port on the chip.

This particular program reads data in from the keyboard. The numeric field is written first and the alpha field is written second. If it is a numeric field, the data are converted to BCD and stored in an allocated memory field. If it is alpha data, it is written to an allocated memory field.

The Monitor Program 375

Any encoding or decoding is done in the stor­ age routines.

T. Van Sickle August 1, 2000 */

#include “phone.h”

Epro able;

main()

{

char name[ALEN]; char number[NLEN]; Epro *epro;

int c;

#ifndef DOS

inituart(); /* initialize the uart to 9600 b/s */

#endif

epro=&able;

reset(&epro); FOREVER

{

c=getchar();

fflush(stdin); /* needed for the PowerC compiler */ switch(c)

{

case ‘n’: /* new entry */

puts(“Enter new number and name\n”); get(number,NLEN);

get(name,ALEN);

saveit(name,number,&epro);

break;

case ‘a’: /* print the next entry */ printafter(&epro);

break;

case ‘s’: /* show all */ printout(&epro);