Talking Electronics PIC Theory

LIBRARY
OF
ROUTINES
Page0-to-ProgramJumps


PAGE0, PAGE1 
These terms do not involve '508A programming however, since we are using a PIC'84 chip in the Pseudo'508A module, Page0 and page1 instructions are needed in the "SetUp" routine. 
The program in the PIC'84 is situated at page0. This is also called Bank0. The TRIS registers (TRISA and TRISB) are located in Bank1 (Page1) and to get to page1, bit5 in the Status register (address 03h) must be SET. 

The instruction is: BSF 03,5 
When the micro is turned on, it comes on with Page0 being the page you can access. To access Page1, the instruction BSF Status,5 takes the program to Page1. 
There are three ways to move (load) a value into the TRISB register: 

                  MOVLW xx 
                  MOVWF TRISB 

                 BCF TRISB,0          ;Make GP0 output 
                 BCF TRISB,1          ;Make GP1 output 
                 BSF TRISB,2          ;Make GP2 input 

                  MOVLW xx 
                  MOVWF 86h 

After the TRISB register has been loaded with the value to make the required port-lines input or output, the program must be taken back to Page0 (bank0) so the program can be placed at page0. The instruction is: BCF 03,5 
See Set-Up for instructions. 

PAUSE 
- See also Time Delay for 0.1 sec delay and 0.25 second delay 
Pause is the same as DELAY. It is a 1 millisecond delay, designed to operate with a 3.579545MHz colour-burst crystal. 
If you have an RC oscillator at about half this frequency, the Pause routine will take 2 milliseconds to execute. 

To call Pause, use the instruction: 

CALL Pause 

After Main, type the following sub-routine: 

Pause        MOVLW EB          ;Put 235 cycles in W 
                 MOVWF 1C 
Loop1        MOVLW 0B           ;Put 11 cycles in W 
                 MOVWF 1D 
Loop2        DECFSZ 1D,1 
                 GOTO Loop2 
                 DECFSZ 1C,1 
                 GOTO Loop1 
                 RETURN 

If you want Pause for 2 milliseconds type: 
                CALL Pause 
                CALL Pause 

Pause_mS 
If you want to pause for more than a few milliseconds, Call Pause_mS. It will produce a delay from 1 millisecond to 9,999 milliseconds. 
Before calling Pause_mS, place the value of the delay you require in files 1A and 1B. 
Files 1A and 1B are set up for 00 01 to 99 99 milli-seconds, where 1A is the Higher and 1B is the lower value. 
E.g: For a delay of 2 milliseconds, load the value 00 02 into 1A and 1B via W then call Pause_mS: 

               MOVLW 00 
               MOVWF 1A 
               MOVLW 02 
               MOVWF 1B 
               CALL Pause_mS 

The values in 1A and 1B must be in hex. Use the following table to find the hex values: 

           05 = 05               55 = 37h 
           10 = 10               60 = 3C 
           15 = 06               65 = 41h 
           20 = 14h             70 = 46h 
           25 = 19h             75 = 4B 
           30 = 1E               80 = 50h 
           35 = 23h              85 = 55h 
           40 = 28h             90 = 5A 
           45 = 2D               95 = 5F 
           50 = 32h              00 for 1A = 00 
                                      00 for 1B = 01 

Examples: 

300 milliseconds = 03 00 
625 milliseconds = 06 25 
1,100 milliseconds = 01 10 
5 seconds = 50 00 
10 seconds = 99 99 

Place the Pause_mS sub-routine after Main: 

Pause_mS 
            MOVF 1B,0             ;Move 1B to W 
            MOVWF 19h           ;Move W to 19h 
Loop1   MOVLW F8             ;Put 248 cycles in W 
            MOVWF 1C            ;Put 248 into 1C 
Loop2   MOVLW 0B             ;Put 11 cycles in W 
            MOVWF 1D             ;Put 11 into 1D 
Loop3   DECFSZ 1D,1 
            GOTO Loop3 
            DECFSZ 1C,1 
            GOTO Loop2 
            DECFSZ 19h,1 
            GOTO Loop1 
            INCF 1A,1 
            DECFSZ 1A,1 
            GOTO Loop4 
            RETURN                  ;Return to Main etc 
Loop4   MOVLW 64h            ;Put 100 loops into W 
            MOVWF 1B             ;Load 1B with 100 
Loop5   MOVLW F8              ;Put 248 cycles in W 
            MOVWF 1C             ;Put 248 into 1C 
Loop6   MOVLW 0B              ;Put 11 cycles in W 
            MOVWF 1D              ;Put 11 into 1D 
Loop7   DECFSZ 1D,1 
            GOTO Loop7 
            DECFSZ 1C,1 
            GOTO Loop6 
            DECFSZ 1B,1 
            GOTO Loop5 
            DECFSZ 1A,1 
            GOTO Loop4 
            RETURN                 ;Return to Main etc 

Pause_mS uses the 1 millisecond routine and executes it "X" number of times. If the value is 315mS, for example, it executes the routine 15 times then looks at the high value (03). 
If the value is zero, it detects the zero by incrementing 1A then using the instruction DECFSZ. The result will be zero and the sub-routine will return to the Main program. 
If the high value is 1 or greater, the 1mS routine will be called 100 times (64h times), for each unit in the high file, then return to Main. 
The secret to creating a delay routine is to nest the files and load the very inner file with a fairly low value. This way you can increment or decrement the next inner file by a value of one and it will have 
the smallest effect on the overall delay time. This is how you fine-tune the delay to the exact time. 
Basically, to work out the timing for the delay, the micro divides the clock by 4 and the result is a length of time called a Machine Cycle or Instruction Cycle. Each instruction takes 1 Instruction-cycle 
except for any program branches such as GOTO. Add up the Machine cycles for the nested delay and you have the total time for execution of the routine. 
For the 1mS delay the timing is worked out via the following formula: 
1C(1B x 1A x 3 + 1B x 5) + 1C x 5 

PC BOARDS 
When making a PC board, the unused pins of the port(s) should not be connected to ground or positive but left OPEN. It is best to take each one to a solder land and connect another solder land (having 
a hole) to the pad so that a component such as a test LED can be connected at some later date. 
Leave the port line OPEN and configure the line as an OUTPUT. Write a zero (LOW) to the line and it will consume the least power. 

PIC12C508A 
All the programs and information in this chapter refers to a PIC12C508A microcontroller. See Converting '508A programs to PIC'84. 

PIC16F84 
- See converting '508A programs to PIC'84. 
The PSEUDO'508A uses a PIC16F84 microcontroller to mimic a '508A microcontroller. 
Programs written for a '508A can run directly in a PIC'84. The reason we do this is because the '84 can be re-programmed, while the '508A is a One Time Programmable chip. 
The only instruction to be changed for a PIC'84 or Pseudo'508A is the accessing of the in/out register (TRIS in the real '508A). 

The instruction: 
         TRIS 06 

must be replaced with: 
             BSF 03h,5         ;Select Page1 
             MOVLW 00 
             MOVWF 06,1 
             BCF 03h,5         ;Select Page0 

The value to be placed in W depends on the arrangement you require for the input and output lines. 
In the '84, the in/out ports (PortA and PortB) are at page0. The control registers for these ports (the TRISA and TRISB registers) are at page1(also called bank1). You have to get to page1 (bank1) via the instruction BSF 03h,5 and load the TRISB file (register) with the appropriate value. When in page1 (bank1) the TRISB register has the address value 06. This is shown in the routine above as MOVWF 06,1. The routine then selects page0 via the instruction BCF 03h,5. 
With the '508A you can go directly to the TRIS file. 

PIEZO 
A Piezo is a device that produces a loud sharp tone when a voltage is placed across it then removed. It takes very little current to drive the device and can be driven directly from any of the outputs of the '508A. 

POLLING 
Reading an input within a loop (such as a Main routine). 

POT 
POT is routine to measure a potentiometer, photocell, thermistor or any variable resistance in the range 0k to approx 50k. 
The device must be connected as shown in the diagram. As the variable resistor changes resistance, the mark-space ratio from GP1 changes and this causes the LED to alter in brightness. If a motor is connected to GP1 via a buffer transistor it will increase in speed as the pot is rotated. 
POT routine has to be set up the first time the chip is turned on. 
To set up POT, turn the potentiometer to FULL resistance and supply power to the chip. The LED will flash for 0.5 sec. Turn the pot to minimum resistance. The LED will flash again and immediately take 
a reading. 
The set-up is complete. Turn the pot and the LED will alter in illumination. 

This routine can be used to vary the speed of a motor or the brightness of a lamp. Simply put a buffer transistor on output pin GP1, via a buffer resistor, and the motor can be controlled or the lamp varied 
in brightness. 
The set-up routine for POT must be placed in the set-up section. This is at address 000. 

Set_Up        CALL PotSetup 
                  GOTO Main 

Before Main, place the PotSetup sub-routine: 

PotSetup 
                  CALL HiVal        ;Disregard 1st result 
                  CALL HitVal 
                  MOVF 1F,1        ;Move 1F to W. Move 
                  MOVWF 18h      ; "HighVal" count to 18h 
                  MOVLW 00        ;Load W with 000 0000 
                  TRIS 06             ;Make GP1 output 
                  BSF 06,1           ;Make GP1 HIGH 
                  MOVLW 08        ;Put 8 into 1C for 1 sec 
                  MOVWF 1C       ; turn-on for LED 
                  CALL Delay        ;1 sec delay 
                  BCF 06,1           ;Make GP1 LOW 
                  MOVLW 20        ;Put 20 into 1C for 4 sec 
                  MOVWF 1C       ; turn-on for LED 
                  CALL Delay        ;4 sec delay 
                  BSF 06,1           ;Make GP1 HIGH 
                  MOVLW 08        ;Put 8 into 1C for 1 sec 
                  MOVWF 1C       ; turn-on for LED 
                  CALL Delay        ;1 sec delay 
                  CALL LoVal        ;Disregard 1st result 
                  CALL LoVal 
                  MOVF 1F,0        ;Move 1F to W. 
                  MOVWF 19h      ; "LowVal"" to 19h 
                  RETURN 

 Hi_Val       MOVLW FF 
                  MOVWF 1B        ;1B is delay value 
 HV1          CLRF 1F              ;Carries Pot value to file 
                  MOVF 1B,0         ; create value for 1F via 1B 
                  MOVWF 1C        ; 1F must be 250+ 
                  MOVLW 00         ;Load W with 00 
                  TRIS 06               ;Make all output 
                  BSF 06,2             ;Make GP2 HIGH 
                  MOVLW FF         ;Delay to charge cap 
                  MOVWF 1A 
HV2           DECFSZ 1A,1 
                  GOTO HV3 
                  BCF 06,2            ;Make GP2 LOW 
 HV3           MOVLW 04        ;Load W with 000 0100 
                  TRIS 06              ;Make GP2 input 
                  ANDWF 06,0      ;AND W with input port 
                  BTFSC 03,2        ;Test Z flag in STATUS 
                  GOTO HV5         ;Input LOW, end counting! 
                  INCF 1F,1           ;Input HIGH, Inc count file 
 HV4           DECFSZ 1C,1 
                  GOTO HV4 
                  GOTO HV3 
 HV5           MOVLW 05        ;See if 1F is 5 off 256! 
                  MOVWF 1D 
                  MOVLW FF        ;Compare 1F with W 
 HV6           XORWF 1F,0 
                  BTFSC 03,2 
                  RETURN              ;1F will come out 250! 
                  INCF 1F,1 
                  DECFSZ 1D,1 
                  GOTO HV6 
                  DECF 1B,1 
                  GOTO HV1 

 LoVal         MOVF 1B,0           ; create value for 1F via 1B 
                  MOVWF 1C ; 
                  CLRF 1F               ;Carries Pot value to file 
                  MOVLW 00           ;Load W with 00 
                  TRIS 06                 ;Make all output 
                  BSF 06,2               ;Make GP2 HIGH 
                  MOVLW FF           ;Delay to charge cap 
                  MOVWF 1A 
 LV1           DECFSZ 1A,1 
                  GOTO LV1 
                  BCF 06,2               ;Make GP2 LOW 
 LV2           MOVLW 04            ;Load W with 000 0100 
                  TRIS 06                 ;Make GP2 input 
                  BTFSS 06,2           ;Test GP2 
                  RETURN                ;Input LOW, end counting! 
                  INCF 1F,1              ;Input HIGH, Inc count file 
 PV3           DECFSZ 1C,1 
                  GOTO LV3 
                  GOTO LV2 

HighVal will be placed in file 18h and LowVal will be in file 19h. 

In the Main program, call Pot: 
             CALL Pot 

Before Main, include the Pot sub-routine: 
               Pot 

PROGRAM LAYOUT 
Programs should be laid out as follows: 

StartUp       --------- 
                  --------- 
                  --------- 
                  GOTO Main 

Table1         ADDWF 02, 1 
                  RETLW data 
                  RETLW data       ;up to FE Maximum 

Sub-routine1: 
GetKey        --------- 
                   --------- 
                   --------- 
                   RETURN 

Sub-routine2: 
Convert1       --------- 
                   --------- 
                   --------- 
                   RETURN 

Sub-routine3: 
Display1       --------- 
                   --------- 
                   --------- 
                   RETURN 

Main            --------- 
                   --------- 
                   CALL GetKey 
                   CALL Table1 
                   CALL Convert1 
                     --------- 
                    GOTO Main 

PROGRAM JUMPS 
See Calculated Program Jumps.