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

Other Program Items 207

mine if the PWM signal is to be turned on. If flag.PWM is set, the PWM code will be executed. When this routine is entered, TCMP2 will be reset to zero. The first instruction sets TCR.OLVL2 so that TCMP2 will be on at the next output compare. The next instruction, TCR.FOVL2=1 , sets the force overflow bit for TCMP2 which will cause this bit to be turned on since TCR.OLVL2 is set. This time is the beginning of the on period of the PWM signal.

The next instruction

TCR.OLVO2=0;

is so that TCMP2 will go off or be reset at the next output compare 2. Control is then passed to the main line of code. When TCMP2 oc­ curs, the output will return to 0 and an interrupt will occur. This interrupt is detected by the first lines of the interrupt service routine.

One could write a code sequence that would generate the mirror image signal to that above. That is, the off time would be controlled by TCMP2 and the on time would be the difference between the time of TCMP2 and the main time base.

Other Program Items

Several other small programs come to mind that are very useful in programming microcontrollers. With these small parts, it is usu­ ally desirable to avoid library functions and, if possible, use a bag of tricks to arrive at the desired results. For example, dealing with num­ bers for either input or output offers a good place to exercise some experience over expedience. One case where it is often important to minimize code space is in generating binary coded decimal (BCD) numbers from integer numbers to output from a computer. Perhaps the most direct approach to accomplish this conversion is as follows:

/* convert a binary number less than 100 to BCD */

unsigned char convert_bcd(unsigned char n)

{

unsigned int result; if(n>99) return 0xff; result=n/10<<4; result += n%10;

208 Chapter 4 Small 8-Bit Systems

return result;

}

Listing 4-8: First BCD Conversion

This small function takes an 8-bit character n that is less than 99 and converts the number into one 8-bit result. The upper nibble is the number of tens in the number and the lower nibble is the number of units. A hexadecimal number 0xff is returned if the number is greater than 99. Note that the calculation requires an integer divide opera­ tion and a modulus operation which is equivalent to a divide operation. The code to execute the divide and modulus operations must be asso­ ciated with this function to complete its task.

Another approach is shown below. This approach avoids any exter­ nal function calls and actually requires less total code than the version in Listing 4-8, even though the C code is somewhat longer. In this case, the while loop essentially divides the input number by 10 and places the result in the most significant nibble of the result.After the tens have been removed from the number, all that is left is the units. This value—the number of units—is ORed on the result before it is returned.

/* convert a binary number less than 100 to BCD */

unsigned char convert_bcd(unsigned char n)

{

unsigned int result;

if(n>99) return 0xff; result=0; while((n-10)>=0)

result+=0x10;

n+=10; result += n;

return result;

}

Listing 4-9: Second BCD Conversion

The function shown below was originally written for use on a M68HC05, but was later used on a M68HC11 as well. A two-digit number must be sent to a seven-segment LED display. The number to be shown is contained in the memory locations for tens and units.

Summary 209

The numeric display takes four inputs that are merely the BCD value of the number to be shown. With this particular display, a 4-bit num­ ber between the values of 0 and 9 will be displayed. If each of the four input lines to the display is turned on, the display will be turned off. The parameters passed to the function—high and low—are flags to indicate whether the corresponding output is to be turned on.

void display(int high, int low)

/* Display the contents of units and tens on the appropriate LED displays. High corresponds to tens, and low corresponds to units. If the proper argument is TRUE, the corresponding LED will be turned on. If the argument is FALSE, the LED will be turned off. */

{

unsigned int save; save = tens<<4; save |= units70x0f; PORTA=save; if(!high)

PORTA |= 0xf0; if(!low)

PORTA |= 0xf;

}

Summary

In this chapter, we have discussed programming techniques for a few of the more important peripheral components found on microcontrollers. Timers and ADC applications will be reconsidered in later chapters. In later chapters, serial communications, attendant programming of look-up tables, interpolation between data points in look-up tables, and synchronous communications from standard digi­ tal I/O pins rather than an SPI will be covered. Some small 8-bit microcontrollers have pulse width modulation (PWM) outputs that can be used as a digital-to-analog converter (DAC). Often the ranges available from these fixed PWM systems are not satisfactory for the required application. Other methods of accomplishing the PWM operation will be discussed in later chapters.

210 Chapter 4 Small 8-Bit Systems

Many of the peripheral components found on the small 8-bit de­ vices are found on larger microcontrollers. The next chapter introduces a group of larger microcontrollers, the M68HC11 family. The com­ piler used for the development of the M68HC05 code does not extend to the M68HC11 family. Therefore, the source code will look a little different in the following chapters, but it will still be all C. To gener­ ate code for the M68HC05, the compiler has had to “bend” the concepts of ANSI C to create code that would work with that family. Larger microcontrollers accommodate more of the large computer features so use of ANSI C is possible.