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

376 Chapter 7 Advanced Topics

break;

case ‘r’: /* reset the system */ reset(&epro);

break;

}

}

}

Listing 7-12: Monitor Program

The SAVEIT() Routine

The saveit() function receives the data entered from the keyboard in monitor(), encodes these data and saves the result in EEPROM for later use. This program is set up to save the data in a linked list. The linked list is an array DLEN, found in phone.h, long and each member of the list is of the type Entry. These data are stored in the main data array and access to these data is made through the values stored in the corresponding Entry for each set of data.

In the header file phone.h, several macros are defined that make it somewhat easier to code this function. The first three entries in the data array are used for special purposes. Therefore, these values are renamed as macros to make the code more understandable. These macros are:

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

Useful names can now be used rather than the cryptic actual names of these various memory locations.

On entry to this function, both the name and number parameters are encoded and the result is saved in the array name[] and number[] respectively. The next block of code determines if there is enough room in the EEPROM array to store all of the data. In the event that there is not enough room, the message “*** buffer full***” is sent to the output and control is returned to the monitor program when return is executed.

/************************************************ This program works in conjunction with moni­

tor(). It receives the input found in monitor

The SAVEIT() Routine 377

which then sends the information to this function, saveit(). The data that arrives is in the form of two binary strings. The first string, the name, is Huffman encoded and the second string, the phone number, is bcd encoded. These data are to be stored in the EEPROM. A linked list that uses indicies rather than pointers is used. The EEPROM is broken into two fields. The first field is an array of the type Entry. This array is DLEN long. The next field is an array that contains the re­ mainder of the EEPROM. This array is an array of type unsigned. It will mostly contain data that has been encoded. The first three entries in the array are special. The first field contains the index to the next unused entry in the array. The second field is the index to the start of the list and the final field contains the number of entries in the list.

************************************************************************/

#include “phone.h”

void saveit(char *s,char *n,Epro *epro)

{

int i,j,sl,nl; unsigned name[ALEN]; unsigned number[NLEN];

sl=encode(s,name,ALEN);/* encode both the name and */ nl=numbdup(n,number,NLEN);/* the number */

/* store encoded data on the end of the array */

if(NEXT_OPEN+sl+nl>DATAPROM)/* do not overwrite the array */

{

puts(“***buffer full***\n”); return;

}

for(i=NEXT_OPEN,j=0;j<sl;i++,j++)

epro->data[i]=name[j]; /* save the name then the number */

378 Chapter 7 Advanced Topics

for(j=0;j<nl;i++,j++) /* at NEXT_OPEN */ epro->data[i]=number[j];

epro- >header[LIST_ENTRIES++].dataindex=NEXT_OPEN;

NEXT_OPEN+=sl+nl;

if(LIST_ENTRIES>=1) /* no entries in list never 0 */ epro->header[LIST_ENTRIES-1].next=LIST_ENTRIES;

}

Listing 7-13: The saveit() Function

If there is enough room in the EEPROM array to store the new data, the encoded name and the encoded number are both written into the array at the appropriate location. Recall that the encode routines return the lengths of the encoded data. NEXT_OPEN is the next unused entry in the array. After the data are written to the array, the new value for NEXT_OPEN is calculated by adding the length of the two encoded arrays to the old value.

Finally, if there is more than one entry in the array the index for the new entry, LIST_ENTRIES, will be put in the next location of the previous entry, epro->header[LIST_ENTRIES-1].next.

The printout() and the printafter() Functions

These two functions are almost the same. Therefore, they will be discussed together. In both cases, control is returned to the calling program if there are no data to be printed out. The printout() routine starts at the beginning of the list and prints the entire contents of the EEPROM. Prior to the printout, the contents are decoded. Both decode routines return a new line character at the end of the data stream along with a null character to indicate the end of the line. Notice in the printout() function, the data starts at the start of the list and cycles through all of the contents of the list.

#include “phone.h”

void printout(Epro *epro)

The printout() and the printafter() Functions 379

{

char na[ALEN],nu[NLEN]; int i,j,k,count=0;

if(LIST_ENTRIES==0)

return; /* no entries */ k=START_OF_LIST;

do

{

i=epro->header[k].dataindex; j=decode(&epro->data[i],na); puts(na); putbcd(&epro->data[i+j+1],nu); puts(nu); k=epro->header[k].next; count++;

}

while(count<LIST_ENTRIES && count<DLEN);

}

Listing 7-14: The printout() Function

Listing 7-15 contains the printafter() routine. Here, the routine cycles through the data, decodes it and prints it out one Entry at a time. In this case, the parameter k is static and it starts with the value 0. This is the value of the index to the first Entry in the array. After each output, k is incremented and so is count. Whenever count attains the value LIST_ENTRIES, all of the data in the memory has been printed out. Then count is restored to 0 along with the value of k being set to 0. This action causes the data in the array to be printed out one field at a time and when all of the data are sent out, it is restored to the beginning of the array and recycled.

#include “phone.h”

void printafter(Epro *epro)

{

char na[ALEN],nu[NLEN]; int j,i;

static k=0,count=0;

380 Chapter 7 Advanced Topics

if(LIST_ENTRIES==0)

return; /* no entries to decode */ i=epro->header[k].dataindex; j=decode(&epro->data[i],na);

puts(na); putbcd(&epro->data[i+j+1],nu); puts(nu);

k++; if(++count==LIST_ENTRIES)

{

count=0;

k=0;

}

}

#ifdef DOS

void puts(char *s)

{

char *sp; sp=s;

while(*sp!=’\n’ && *sp!=’\0') putchar(*sp++);

putchar(‘\n’);

}

#endif

Listing 7-15: The printafter() Function

When developing and testing this program with the DOS system, I found it necessary to include the new puts() function. When the program is moved to operate on the HC12, it will be necessary to include separate i/o functions to be discussed below. The i/o functions are not included in the DOS version of the program. Therefore, the puts() function that is added to the end of the printafter() function above is included. This little function will be discarded whenever the parameter DOS is not defined. In that case, the i/o functions should be included.