The Instruction Set Part 4 (PIC Microcontroller)

Example 5.3

Write a routine to convert a binary number of magnitude no greater than 63h (decimal 99) in File 20h to two BCD digits in File 21:2h ordered as Tens:Units.

Solution

A possible algorithm to implement this binary to BCD conversion is to divide by ten; this generates a quotient between 0 and 9 (remember the maximum value is 99) and a remainder. The quotient is the number of tens and the remainder will be the number of units.

Program 5.8 Bi-quinary error detection.

Program 5.8 Bi-quinary error detection.

We have already seen how to divide by an arbitrary variable datum byte in Program 5.3. Here in Program 5.9 we wish to divide by a constant ten. This simplifies the coding somewhat with the addlw -d’10′ (or addlw -0Ah) instruction used to take away the literal ten. Keeping a count in the TENS file register gives the number of subtractions until a borrow is generated. The required number of tens is one less than this tally; that is the number of successful subtractions. Adding that one extra ten back again to the residue gives the remainder, which is the units tally.


Example 5.4

Using Program 5.2 as a template write a program to evaluate the average temperature over the 24 hours.

Solution

Finding the average involves walking through the array adding each element to a 2-byte grand total. On completion divide by 24 to give the function:

tmp18347_thumb[2][2][2]

Program 5.9 Binary to 2-digit BCD conversion.

Program 5.9 Binary to 2-digit BCD conversion.

This gives the task list:

1. Clear AVERAGE.

2. Point to Temp[0] (i = 0).

3. DO

(a) Add Temp[i] to the 2-byte grand total.

(b) Increment i.

(c) Repeat WHILE i < 24.

4. Divide by 24.

5. End.

Program 5.10 directly implements the task list, summing each datum byte by adding to the double-byte location File48:9h, which has been cleared before entry to the loop. Division is accomplished by repetitively subtracting 24 from the final total. This is similar to the ^10 routine of Program 5.9 but this time the single-byte constant is taken off the double-byte dividend. The number of successful subtracts is the quotient, which in this case is the truncated average. Of course it would be more accurate to round up if the remainder was more than half of the divisor.

Example 5.5

Write a routine to multiply a byte in File 22h by ten. The 2-byte product is to be located at File 23:4h givingtmp18349_thumb[2][2][2]

tmp18350_thumb[2][2][2]where File 21 h is used to extend the single-byte multiplicand to a 16-bit double-byte datum.

Solution

The task list implemented in Program 5.11 splits the x10 task into a x8 + x2 operation. Thus:

1. Multiply multiplicand by eight (shift left three times).

2. Multiply multiplicand by two (shift left once).

3. Add the two 16-bit partial products.

4. End.

Program 5.10 Average daily temperature.

Program 5.10 Average daily temperature.

Program 5.11 multiplication by ten.

Program 5.11 multiplication by ten.

The coding copies the 1-byte multiplicand into the lower byte of the product to be. Clearing the upper byte extends the datum to 16 bits. Clearing the Carry flag and then shifting left three times gives the x 8 subproduct. As the upper byte is initially clear then the Carry flag is always zero after each double-byte shift, as it is going into the second x2 shift routine. This is done on the extended multiplicand memory space and the resulting subproduct added to first datum. This addition is simplified as the shifted upper byte of the x 2 subproduct is small and so any carry from the lower byte addition is accounted for by simply incrementing the upper byte of this datum before the upper bytes are added. There will be no carry out from this latter addition.

Self-assessment questions

5.1 Can you deduce what function the following code fragment performs on the data byte in the Working register?

tmp18353_thumb[2][2][2]

5.2 How could you extend Example 5.3 to give an outcome as packed BCD in File 21 h? Hint: Consider making use of the swapf instruction.

5.3 Develop Example 5.3 to give a 3-digit BCD outcome; removing the restriction that the original binary byte should be limited to decimal 99. The outcome is to be in File 21:2:3h.

5.4 Extend Example 5.1 to decrement a quad-precision 32-bit word located at File 26:7:8:9h, most significant byte first.

5.5 Example 5.4 evaluated the average of an array of hourly temperature samples by summing all bytes and then subtracting 24 until the residue dropped below zero. Write an extension to this program to round the average to the nearest integer; that is if the remainder is more than 12 then round up.

5.6 Write a routine to multiply a byte in File 22h by 13. The 2-byte product is to be located at File 23:4h. The memory map for this istmp18354_thumb[2][2][2]

where File 21 h is used to extend the single-byte multiplicand to a 16bit double byte datum. Note that this will require three shift and add processes.

5.7 A simple digital low-pass filter can be implemented using the algorithm:

tmp18355_thumb[2][2][2]

where Sn is the nth sample from an eight-bit analog to digital converter located at Port B.

Write a routine assuming that the three byte memory locations to store Sn, Sn-1 and Sn-2 are located at File 20:1:2h respectively. The outcome Array [i ] is to be located at File48h.

5.8 A certain television show has eight contestants which are evenly divided into Team A and Team B. Each member has a switch, giving logic 1 when pressed, which may all be read simultaneously by the microcontroller at PortB. Team A switches appear on the lower four bits of the port.

Write a routine that will:

• Decide when a response to the question has been made – any switch closed.

• Determine the team identity that has responded, by clearing File 20h for Team A and setting it to any non-zero value to signify Team B.

• Ascertain which team member pressed his or her switch by putting the member number 0-3 in File 21 h.

Next post:

Previous post: