ChipCenter Questlink
SEARCH CHIPCENTER
Search Type:
Search for:




Knowledge Centers
Product Reviews
Data Sheets
Guides & Experts
News
International
Ask Us
Circuit Cellar Online
App Notes
NetSeminars
Careers
Resources
FAQ
EE Times Network
Electronics Group Sites

Recycle Your Code


Circuit Cellar Online
THE MAGAZINE FOR COMPUTER APPLICATIONS
Circuit Cellar Online offers articles illustrating creative solutions
and unique applications through complete projects, practical
tutorials, and useful design techniques.

RECYCLE YOUR CODE

Lessons from the Trenches Conversion and Optimization Techniques
by Stephen Bowling

Start ı A Code Example ı Optimizing the Code Conversion ı Sources and PDF

A CODE EXAMPLE

One of the best ways to discuss code conversion and optimization is to use some real source code. The example program that Iıll use was written to operate on a PIC16C74B device and implements a simple digital thermometer. Itıs not a complex program, but it demonstrates many of the code conversion issues that Iıll discuss. Figure 1 shows a block diagram of the application. A resistor/thermistor combination is connected to channel 0 of the A/D converter. Two seven-segment LED displays are multiplexed to PORTD of the MCU. Timer0 and Timer1 are used to time the display updates and A/D conversions, respectively, that are handled in an interrupt service routine. The A/D result is used as an offset for a temperature lookup table. Each byte in the lookup table contains a packed BCD temperature result. The resulting BCD values are then used to obtain the proper LED segment data in a second lookup table.

Figure 1ıA digital thermometer makes a great code-conversion example. This is the simplified connection diagram of the thermometer.

 

The original code written for the PIC16C74B is given in Listing 1, which is available for downloading. Let me show you how to convert the code so that it will be compatible with a PIC18C452 device. The PIC18C452 is pin-to-pin compatible with the PIC16C74B and has a set of peripherals that are compatible with the PIC16C74B with enhancements.

Letıs walk through the code and perform the minimal conversion. The first two lines in the code specify the processor type and the device definition file. The first thing you need to do is change these for the appropriate processor:

LIST P = 18C452
include <p18c452.inc>

The device definition file specifies symbolic names for all of the registers and control bits associated with the device. Itıs always good practice to use register and bit definitions supplied by the vendor to avoid any naming convention issues.

Definitions for numerical constants and data storage variables are also included at the beginning of the source code. For example, the start address for the data lookup tables has been defined to be 800h. Constants like this one should be defined symbolically at the beginning of the code, because it enhances readability and allows them to be changed without having to sift through many lines of source code.

Want MORE...unique applications, complete projects, practical tutorials, and useful design techniques?

Subscribe to Circuit Cellar magazine

 

Next, youıll need to take care of any register name changes. To begin with, the PIC16Cxxx architecture has one FSR, which is eight bits wide. Because there are three 12-bit FSRs in the PIC18Cxxx architecture, the register names are different. For example, assuming youıll use FSR0, references to the FSR and INDF registers in the PIC16C74B code can be redefined as follows:

#define FSR FSR0L
#define INDF INDF0

The operation of Timer0 is enhanced in the PIC18Cxxx architecture so that it can be used as a 16- or 8-bit timer. Consequently, there are two registers (TMR0H and TMR0L) for Timer0. You can take care of this change with the following #define statement:

#define TMR0 TMR0L

The PIC18C452 A/D converter provides a 10-bit result in two 8-bit registers, ADRESH and ADRESL. The PIC16C74B has an 8-bit A/D converter and a single result register, so youıll need the following #define:

#define ADRES ADRESH

Finally, it is useful to define constants for the IRP, RP0, and RP1 bank selection bits. These bits are not implemented in the ı18Cxxx architecture, nor are they defined in the device definition file.

#define RP0 5
#define RP1 6
#define IRP 7

For minimal conversion, leave all data memory banking statements in the converted code. Any instructions in the code that operate on the IRP, RP0, or RP1 bits have no effect because the bit locations are not implemented.

The interrupt vector origin needs to be changed at this point. Because byte addressing is used in the PIC18Cxxx architecture, the interrupt vector location is changed from 0004h to 000008h. You should also ensure that there is enough space for the program instructions that are located between the reset vector and interrupt vector. These instructions may need to be modified because CALL and GOTO instructions are one-word instructions in the PIC16Cxxx architecture but are implemented as two-word instructions in the PIC18Cxxx architecture.

Next, you need to verify that there are no bit location changes in the SFRs that control operation of the peripherals. For example, the values loaded into ADCON0 and ADCON1 should be verified using the device datasheet to ensure that the A/D converter is configured properly. In most cases, the bit locations will be the same, but there may be differences between devices. You have to be careful here because the assembler will not catch these types of errors in the program. The only indication of a problem you will receive is when the peripheral controlled by the SFR does not operate as expected.

One special case is the SFR that controls Timer0. In the PIC16Cxxx architecture, Timer0 is configured by the OPTION_REG register. This register is not present in the PIC18Cxxx architecture, so you need to change the name to T0CON. T0CON now controls whether the timer is in 16- or 8-bit mode, therefore, you also need to ensure that the correct set-up value is loaded into the register.

In general, it is best not to use hard-coded bit and register values. For example, the two instructions below are equivalent, but the second is preferred:

bsf ADCON0, 0 ; Donıt do this !
bsf ADCON0, ADON ; Preferred !

The code should be checked for any instructions that may be incompatible with the new architecture. When converting from the PIC16Cxxx to the PIC18Cxxx architecture, there are three cases that should be checked. The first instruction is CLRW, which clears the accumulator working register. This instruction is needed in the PIC16Cxxx device family because the working register is not physically addressable. However, the following #define statement makes a simple substitution:

#define CLRW CLRF WREG

The next two instructions that need modification are RLF and RRF, which rotate a register left or right, respectively, through the carry flag. The PIC18Cxxx instructions operate the same but are named differently to indicate usage of the carry flag. Again, two #define statements will make the required substitutions:

#define RRF RRCF
#define RLF RLCF

The final modifications to the code account for differences in the operation of the program counter. Remember, the program counter increments in steps of two in order to maintain word alignment with program instructions. Because of this, any references to the program counter value must be multiplied by two. In the original PIC16C74B source code, the following instructions poll the GO bit in ADCON0 to determine when an A/D conversion has completed:

btfsc ADCON0,GO ; Conversion complete?
goto $ - 1 ; No, keep checking.

The $ symbol represents the present program counter value. The GOTO instruction decrements the program counter value so that the previous instruction is executed.

To operate correctly on the PIC18Cxxx architecture, the code should be modified to the following:

Btfsc ADCON0,GO ; Conversion complete?
goto $ - 2 ; No, keep checking.

It is always good practice to use symbolic address labels. For example, the following code will operate the same on both device families without modification:

Test
btfsc ADCON0,GO ; Conversion complete?
goto Test ; No, keep checking.

The lookup tables will require modification. To implement a lookup table, an offset value is placed in WREG and a CALL is made to the table. The table consists of a series of RETLW instructions, which return from the call with a specific value in WREG. The offset value in WREG is added to the program counter and causes a jump to the desired instruction. After returning from the call to the lookup table, the WREG value is stored in the desired location. An example lookup table is given below:

Movlw Offset ; Table offset value
Call Table ; Call the table
Movwf Result ; Get table result
·    
·   ; other code
·    
addwf PCL,F ; Add offset to PC
retlw Constant2 ; Table entry #2
retlw Constant3 ; Table entry #3
retlw Constant4 ; Table entry #4
retlw Constant5 ; Table entry #5

 

For the lookup table to function properly on the PIC18Cxxx architecture, the offset value must be multiplied by two. This will cause the program counter to be advanced by the correct number of instructions. The lookup table has been modified to operate on the PIC18Cxxx architecture:

Movlw

Offset

; Table offset value

Call Table ; Call the table
Movwf Result ; Get table result
   
  ; other code
   
rlncf

WREG

; MULTIPLY OFFSET BY 2
addwf PCL,F ; Add offset to PC
retlw Constant1 ; Table entry #1
retlw Constant2 ; Table entry #2
retlw Constant3 ; Table entry #3
retlw Constant4 ; Table entry #4
retlw Constant5 ; Table entry #5

 

The minimal modifications to your PIC16C74B source code have now been completed. The code should now be fully functional on the PIC18C452 device. The complete minimal code conversion is provided in Listing 2.

PREVIOUSNEXT


Circuit Cellar provides up-to-date information for engineers. Visit www.circuitcellar.com for more information and additional articles.
For subscription information, call (860) 875-2199, subscribe@circuitcellar.com or subscribe online. ıCircuit Cellar, the Magazine for Computer Applications. Posted with permission.
Click here to get your listing up.

Copyright © 2003 ChipCenter-QuestLink
About ChipCenter-Questlink  Contact Us  Privacy Statement   Advertising Information  FAQ