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

Pulse Width Modulator System 201

The assembly code created by the compiler for this approach is in the address range $11d to $130. This code uses 21 bytes of memory. Careful examination of this code will show that the instruc­ tion at $122 is unneeded, so the code could have been completed in 17 bytes.

The assembly version of the same routine merely adds the two unsigned numbers, and then rotates the result right 1 bit to accom­ plish the divide by 2. The 1-bit rotate accomplishes the same thing as a right shift by 1 bit with the exception that the carry bit is shifted into the most significant bit of the result. The only way the carry bit could be set is by the most significant bits of both addends being 1. The assembly version of the code resides in $132 to $13c and re­ quires 12 bytes of code.

Here is a case where judicious choice of assembly code will provide a significant improvement in the amount of code needed to execute a specific program. The main reason that the assembly ver­ sion is shorter is that the carry bit in the condition code register is available to the programmer from assembly. This bit is completely hidden from the programmer in any high-level language. Therefore, tricks like rotating a bit from the carry into a register are not avail­ able in the high-level language.

EXERCISE

1.Write a routine to average readings from the ADC on a microcontroller, but weight the current reading three times that of the past average.

Pulse Width Modulator System

In this section on programming of the timers, two approaches to the generation of a pulse width modulation (PWM) signal will be discussed. These approaches both use the output compare system of the 16-bit timer.

What is a PWM system? A PWM signal is a periodic signal where the signal is set high for a calculated duty factor, and then the output goes low for the remainder of the period. If you measure a PWM signal with an averaging voltmeter it will have a value equal to the peak voltage times the duty factor of the PWM. Here the duty factor is defined as the ratio of the on time to repetition period of the signal.

202 Chapter 4 Small 8-Bit Systems

Thus, we have created a simple digital-to-analog converter. Many control applications need analog control signals for parts of the sys­ tem. PWM systems on microcontrollers provide an excellent means for providing these analog voltages, so long as the limitations we will discuss below are acceptable to the total system design.

The built-in PWMs in the M68HC05Bx family of devices pro­ vide you with one of two pulse periods: the programmable timer clock frequency divided by 256 or 4096. These frequencies are fixed, and the interval is divided into 256 parts. Therefore, the analog fre­ quency ranges—and the accuracy of the analog reproduction—is limited to one part in 256 over the range of the output.

When using the output compare system to create a PWM, it is possible to achieve a finer analog resolution at slower frequencies, or perhaps a faster signal with poorer accuracy. A PWM created from an output compare system is somewhat more flexible than the usual built-in PWM. With the PWM systems built around the output com­ pare system, the computer is responding to frequent interrupts. When an interrupt occurs, the system status is pushed onto the stack and the address of the interrupt service routine is placed into the program counter. It takes approximately 10 clock cycles to respond to an in­ terrupt after the completion of the executing instruction. Return from an interrupt requires 9 clock cycles. Therefore, it is not possible to accomplish the full goal of a PWM with an output compare system. The goal in this case is to achieve full on at the one extreme input level and full off at the other. The times required to process an inter­ rupt will limit the performance at one extreme, the other or perhaps both when a PWM is implemented with an output compare system.

A first example is shown in the following listing. This example shows the interrupt service routine along with the necessary defines only. It is assumed that the output compare interrupt bit along with the interrupt bit are properly set to allow the output compare 2 to interrupt the processor. Also shown in this example is code to control a second output compare—1—to provide the system with a fixed time base.

In operation, the applications portion of the program must place a pair of complementary numbers, pwm_number and off_count, in place. The sum of these two numbers must equal a constant that establishes the period for the PWM signal. For the M68HC05B4, the

Pulse Width Modulator System 203

period will be 2 microseconds times the total count value. Prior to starting use of the PWM, the bit flag.ON should be reset and the value for count, which is the main time base period count, should be set.

/* bits in flag */

#define ON 0

union both time_cnt;

unsigned long off_count,pwm_number,count; bits flag;

void __TIMER_OC(void)

{

if( TSR.OCF2==1) /* accesses the TSR */

{

if(flag.ON==0)

{

flag.ON=1;

TCR.OLVL2=0; /* Timer Compare 2 off*/ time_cnt.b.hi=OCHI2;/* get start time */ time_cnt.b.lo=OCLO2; /* reset the OCF */ time_cnt.l +=pwm_number; OCHI2=time_cnt.b.hi; OCLO2=time_cnt.b.lo;

return;

}

else

{

flag.ON=0;

TCR.OLVL2=1;/* Timer Compare 2 to on */ time_cnt.b.hi=OCHI2;/* get start time */ time_cnt.b.lo=OCLO2; /* reset the OCF */ time_cnt.l +=off_count; OCHI2=time_cnt.b.hi; OCLO2=time_cnt.b.lo;

return;

204 Chapter 4 Small 8-Bit Systems

}

}

else /* must be that OCF1==1 rather than OCF2

*/

{

time_cnt.b.hi=OCHI1; /* output compare */ time_cnt.b.lo=OCLO1; /* get lo byte */ time_cnt.l +=count; /* time for interrupt */ OCHI1=time_cnt.b.hi;

OCLO1=time_cnt.b.lo;/* reset the OCF */ ms_10++;

return;

}

}

Listing 4-6: ISR For PWM System

Since the interrupt bits are set to allow output compare interrupts, an interrupt will occur. The interrupt service routine will be entered, and the instruction sequence

if( TSR.OCF2==1) /* accesses the TSR */

{

.

.

.

accomplishes two things. First, it determines if the output compare 2 caused the interrupt, and, secondly, it accesses the TSR and arms the reset of the OCFX when the proper lower byte of the output compare register is read later.

For the moment, assume that OCF2 bit is set: the interrupt was caused by a compare in output compare register 2. In this case a test is made to determine if flag.ON is reset. Since the initialization rou­ tine reset this bit, it will be 0. Therefore, the code sequence

flag.ON=1;

TCR.OLVL2=0; /* Timer Compare 2 to turn off*/ time_cnt.b.hi=OCHI2; /* get the start time */ time_cnt.b.lo=OCLO2; /* reset the OCF */ time_cnt.l +=pwm_number;

Pulse Width Modulator System 205

OCHI2=time_cnt.b.hi; OCLO2=time_cnt.b.lo; return;

will be executed. This code is the “on” code for the PWM system. The first instruction in this sequence will set the bit flag.ON, so that this code will not be executed in the next execution of the inter­ rupt service routine. The bit TCR.OLVL2 is the state that will be transferred to TCMP2 pin when an output compare occurs. TCR.OLVL2 is then set to 0 so that TCMP2 will be set low when the next output compare occurs. The code sequence that follows gets the contents of the output compare register 2, increments this value by pwm_number, and places this new value back into output compare register 2. Thus, the time of the output compare is established and the interrupt service routine is exited.

Eventually, the next output compare 2 interrupt will occur. Since the bit flag.ON has been set, the following code will be executed. This code is the “off” code for the PWM system. The first business to take care of is to reset the bit flag.ON so that the on portion of PWM code will be executed the next time into the ISR. TCR.OLVO2 is set so that TCMP2 will go on when the next output compare occurs.

flag.ON=0;

TCR.OLVL2=1; /* Timer Compare 2 to turn on */ time_cnt.b.hi=OCHI2; /* get the start time */ time_cnt.b.lo=OCLO2; /* reset the OCF */ time_cnt.l +=off_count; /*complete the cycle*/ OCHI2=time_cnt.b.hi;

OCLO2=time_cnt.b.lo; return;

The contents of OCR2 are handled as above, but this time their value is incremented by the contents of off_count. The main line code is then re-entered by the use of the return instruction.

There is another approach to generation of PWM signals with out­ put compare systems that will materially aid this problem. However, this approach requires two output compare systems. One output com­ pare system is used to create the time base and the other is used to generate the on or off time. Let’s examine the following interrupt service routine. Output compare 1 is used here to generate the PWM

206 Chapter 4 Small 8-Bit Systems

period. The way that this routine works, it is possible for an interrupt to occur as a result of a compare on output compare 2. This interrupt is to be ignored, and the first five lines of the code below tests for this condition and clears interrupt when it occurs. This interrupt occurs at the end of the on time. Control of the program must be out of this portion of the ISR and in the main line code before the next interrupt caused by OCF1 occurs. The time required for the first five lines of code here is about 18 microseconds, which is the minimum on time.

void __TIMER_OC(void)

{

if(TSR.OCF2==1)

{

ac=OCLO2; /* if interrupt is caused by out­

put*/

return; /* compare 2 reset it and return */

}

time_cnt.b.hi=TCHI; /* get in the TCR */ time_cnt.b.lo=TCLO; /* get lo byte */ time_cnt.l +=count; /* bump the time counter

for next*/ OCHI1=time_cnt.b.hi;/* interrupt */ OCLO1=time_cnt.b.lo;/* reset the OCF */ if(flag.PWM==1)

{

TCR.OLVL2=1;/* Timer Compare 2 to set output */ TCR.FOLV2=1;/* turn on Timer compare 2 output */ TCR.OLVL2=0;/* Timer Compare 2 to reset output*/ time_cnt.b.hi=TCHI; /* get the start time */ time_cnt.b.lo=TCLO;

time_cnt.l +=pwm_number; OCHI2=time_cnt.b.hi; OCLO2=time_cnt.b.lo;

}

}

Listing 4-7: Alternate PWM ISR

The next sequence is the code required to establish the time base. This time base operates on output compare 1. This routine is similar to those discussed above. A bit in the bit field flag is tested to deter­