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

Reset 381

Reset

The reset function is dependent on the system being used. When programming for the DOS-based system, the array that represents the EEPROM is put into a state that simulates erased EEPROM. Then the first three entries in the array data[] are initialized to the proper values. Recall that data[0] will always contain the index to the next open entry in the data[] array. This index is defined by a macro in the phone.h file to be NEXT_OPEN. The next two members data[0] and data[1] contain the index to the starting index into the header array, START_OF_LIST and the number of entries in the list LIST_ENTRIES respectively. The first three members of this array are used as described above. The first available member for storage of data is at the index 3. Therefore, NEXT_OPEN is assigned a value of 3 and both START_OF_LIST and LIST_ENTRIES are initialized to 0. Remember, that this data array is the second member of a structure of the type Epro. An external instance of this structure named able is defined in the file monitor.h, and a pointer to this structure epro is also defined there.

The reset() function is the first in this program that requires code for the DOS implementation that differs from the HC12. When the EEPROM is initialized, all bits in the memory are turned on: the memory is filled with 0XFFFF. Therefore when simulating this memory, the initialization will fill the memory similarly. There is a library function in the Cosmic library, eepera(), that erases the memory. Therefore, when coding for the HC12, this function will be used. The code for the reset() function is shown in Listing 7-16.

#include “phone.h”

void reset(Epro *epro)

{

int i; #ifdef DOS

memset(epro,0xff,EEPROMLEN);

/*make arrays look like EEPROM */

#else

eepera();/* erase the EEPROM with library function */

382 Chapter 7 Advanced Topics

#endif

/* Start the linked list */

NEXT_OPEN = 3;/* next open entry in the list */ START_OF_LIST =0;/* start of the list */

LIST_ENTRIES=0;/* number of entries in the list */ epro->header[0].dataindex=NEXT_OPEN;/* start

the list */ for(i=0;i<DLEN;i++)

epro->header[i].next=END;

}

Listing 7-16: The Reset Function

Input/Output Functions

There are three input/output functions that are usually found in the standard I/O library that we will replace with microcontroller specific code here. These functions are putchar(), getchar(), and puts(). In the first two instances, rather than sending and receiving data from devices like stdout and stdin, all output will go to the serial port on the HC12 and input will come likewise from the serial port. Therefore, these routines will have to be written from scratch. In addition to the direct input/output functions, an initialization function that enables the serial port will be needed. This function must set the bit rate for the serial port and enable both the UART transmitter and receiver. This function is as follows:

#include “hc12.h”

#define BAUD9600 52

#define BAUDREG *(BYTE *)&SC0BDL

void inituart(void)

 

{

 

BAUDREG=BAUD9600;

/* Set the bit rate */

SC0CR2.TE=ON;

/* turn on transmitter */

SC0CR2.RE=ON;

/* and the receiver */

}

 

Input/Output Functions 383

The choice for bit rate for this system is 38.4 kbits per second. To achieve this rate, the baud rate divisor value is given by

BR= Eclk/16 BaudRate

The E clock for the system is 8 MHz. Therefore, the divisor, BR, is 52 when rounded to the nearest integer value.

The register SC0BDL is defined in the header file hc12.h as a type Register, or a collection of eight individual bits. In this case, it is more understandable to put the data into this register as a char rather than as a set of bits. The type of this location can be changed to a type BYTE easily, using the line of code

#define BAUDREG *(BYTE *)&SC0BDL

Read this line of code from right to left. It says to cast a pointer to the memory location SC0BDL onto a pointer to a type BYTE and then dereference it. Therefore, whenever the defined name BAUDREG is used, it accesses the BYTE contents found at the address SC0BDL. This address is defined in the header file hc12.h.

The next two lines of code turn the bits TE and RE in SC0CR2 on. When these bits are ON, both the UART transmitter and receiver will work.

The next function is putchar(). This routine sends the designated BYTE to the serial port. It is necessary to wait until any data in the transmit data register has been completely processed before sending new data to this register. The first line of code does not allow the value of SC0DRL to be altered until the transmit data ready bit, TDRE, is set. Then the value x is stored in the location SC0DRL, which causes the data to be sent to the serial port.

void putchar(BYTE x)

{

while(!SC0SR1.TDRE)

; /* wait until register is ready */ SC0DRL=x; /* send the data out */

}

The last of the I/O functions is getchar(). The getchar() function is a little longer than the putchar()function. This difference is caused by the fact that when a character is read in from the serial port it should be immediately echoed back. Therefore, the entered

384 Chapter 7 Advanced Topics

data are stored in the memory location a and sent out with the instruction putchar(a) before it is returned to the calling program.

BYTE getchar(void)

{

BYTE a; while(!SC0SR1.RDRF)

;/* Wait for data ready */

a=SC0DRL;

 

 

 

putchar(a);

/*

echo

the data and */

return a;

/*

then

return it*/

}

 

 

 

Finally, the puts() function from the standard library does not terminate transmission when it detects a new line character. For proper operation in this program, it should, so the following function was written. Notice that this function terminates whenever either a new line character or a zero character is detected in the input string. Like the standard library puts() it outputs a new line character regardless of the termination of the data.

void puts(char *s)

{

char *sp; sp=s;

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

putchar(‘\n’);

}

An interesting observation: If you look in Chapters 4, 5, 6, and 8 you will find similar routines for other chips. In every case, the functions, even though they are for a broad range of different chips, are the same—a testimonial to the use of a high-level language like C to program our microcontrollers. A listing of these three functions is collected together in Listing 7-17 shown below.

#include “HC12.H”

#define BAUD9600 52

Input/Output Functions 385

#define BAUDREG *(BYTE *)&SC0BDL

void inituart(void)

{

BAUDREG=BAUD9600;/* Set the bit rate */

SC0CR2.TE=ON;

/*

turn on

transmitter

*/

SC0CR2.RE=ON;

/*

and the

receiver */

 

}

 

 

 

 

void putchar(BYTE x)

{

while(!SC0SR1.TDRE)

; /* wait until register is ready */ SC0DRL=x; /* send the data out */

}

BYTE getchar(void)

{

BYTE a; while(!SC0SR1.RDRF)

; /* Wait for data ready */

a=SC0DRL;

 

putchar(a);

/* echo the data and */

return a;

/* then return it*/

}

 

void puts(char *s)

 

{

 

char *sp;

 

sp=s;

 

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

putchar(‘\n’);

}

Listing 7-17: The Input/Output Routines Used with the M68HC912B32 Chip