Chapter 2
100 Helpful Hints


Home
 

Instruction Set for PIC12F629
PIC12F629 data
(pdf)
BlankF629.asm

PIC12F629.inc

See more projects using micros:
Pic A PIC Project

Notepad2.zip     Notepad2.exe 
Library of Sub-routines "Cut and Paste
"
Library of routines:   A-E   E-P    P-Z 

PIC Programmer MkV
P1(list of projects)
P3 The XOR Trick


 

 

Here are lots of helpful hints to get you started in programming. Programming is easy if you follow our suggestion of taking a program from the list of projects and modifying it slightly by changing one or two instructions at a time.
It's a lot more tricky writing a program from the start. And we don't advise this AT ALL.
But if you want to find out about some of the "tricky things" in a program, here is a list of 100 Helpful Hints.
Don't forget to see our Library of routines:   A-E   E-P    P-Z   It covers lots of things.

BINARY, DECIMAL AND HEX
The numbers in your program can be written in binary, decimal or hex.
Here is how to write them:
;Binary numbers are shown as b'00000000' or b'11110001'
;Decimal number are shown as: .10 .255 or d'10' - note the decimal point.
;Hex numbers are shown as: 0Ch, 0ffh, 0x2F, 0x20, 0x0ff  - "0" must be placed before any letter as 0xff will not be read correctly.

You can use a mixture of all three providing you keep to the correct formatting.

Or you can specify the way numbers are to be interpreted by the compiler by adding:
radix binary
radix dec    (a number such as 20 will be treated as a decimal).
radix hex


cblock
A simpler way to list all the names for the files is to use cblock.   A program inside the compiler takes each name and allocates a file, starting at 20h:

           cblock    0x20 (block of constants)
delA     
loops   
display  
jump  
tLOW
tHIGH
tREC  
          endc

cblock is very easy to use. You can add or remove names without having to allocate file numbers.


CALL AND GOTO
The  CALL instruction for a PIC12F629 accesses ALL MEMORY.
Using the:
     call  sub-routine
instruction will send the micro to another address such as a sub-routine and if the sub-routine contains the instruction:
    retlw   00
the micro will go to the next instruction after the call instruction.
If you use
    goto   sub-routine
the micro will go to the sub-routine but when it sees the
  retlw   00
instruction, it will go to a previous call.

 

DEFINING THINGS
When writing a program, the layout must be in columns so that the assembler will know how to interpret each item. This layout is called a TEMPLATE and the program is saved as .asm  (assembly program)
The first column contains Labels.
The second column contains Directives (such as equ, end) and Mnemonics (instructions)
The third column contains Operands, and
The fourth column contains Comments (such as ;output HIGH  ;test zero bit)

Pink Labels     Blue Directives        Black Mnemonics                                Red Operands         Green - Comments

del1     equ     0x20     ;store del1 in file 20 hex

           movlw   0x34    ;load w with 34  hex
loop    movwf   del1
          
addwf   del1,w
          
goto      loop
          
sleep

           end

During the running of a program you may want to decrement a file to create a delay.
The file is called a temporary storage and a set of files from 20h to 5Fh is available in the PIC chips we are promoting.
At the beginning of a program, each file that you want to decrement, or store a number of loops, or hold a value for displaying later, or hold the jump value for a table, is given a name such as: delA, loops, display, jump. These files are sometimes called Variables.
Each name is then allocated a  file, starting at 20h, 21h, 22h, etc.
delA       equ   20h
loops      equ   21h
display    equ   22h
jump      equ   23h
 



goto  $+1     goto  $-1       goto  $
The instruction:
     goto   $+1
sends the micro to the next instruction but takes 2uS.  (A nop instruction takes 1uS)

The instruction:
     goto   $-1  
sends the micro to the previous instruction.  This can create an endless loop!

The instruction:
     goto   $  
creates a halt as $ represents the current address.

You can also use this terminology to go to an instruction before a sub-routine, such as:
     goto   delay-1
This sends the micro to the line before the delay sub-routine. This allows you to use the delay sub-routine for different timings. The line before the label: "delay" has a load-value of 3Fh and this can be used in the sub-routine. Or you can preload a value into w and go to the sub-routine at the actual label: delay.
This is how the delay sub-routine is structured:

            movlw     3Fh
d
elay    movwf     temp
            decfsz    temp,w      ;the decremented value of temp is placed in w
            goto       delay
            retlw       00

Normally we use the instruction decfsz temp,f   where the temp file holds the decremented value. But to create a multiple input delay sub-routine we need to use: decfsz temp,w and the previous instruction: movwf     temp  to put the decremented value into temp.  
To use the load value 3Fh, use the instruction: call    delay-1
To load temp with any other value, use the instructions:
         movlw      xxh
         call          delay

DsPIC
Some of the latest PIC chips have part numbers such as  dsPIC30F1010. These are classified as Digital Signal Controller chips as they have the capability of  processing digital signals and contain a fully implemented digital signal processor (DSP). 

IN/OUT PORT
The IN/OUT port on a PIC12F629 is file 05h. This port corresponds to pins 7, 6, 5, 4, 3, and 2 for GP0, GP1, GP2, GP3 GP4 and GP5.
Remember: GPIO,3 (GP3) (pin 4) is an INPUT-ONLY pin.
When writing a program, use GPIO,0 GPIO,1 GPIO,2 GPIO,3 GPIO,4 GPIO,5 in your program and the compiler will do the rest. (GPIO = General Purpose Input/Output).
For instance, If you want to SET (make HIGH) pin 7, you must do two things:
1. Make sure GPIO,0 is an OUTPUT bit by making the corresponding bit in the TRISIO register "0."  This is done via the following instructions: Remember: "0" = output,  "1" = input

    bsf         status, rp0      ;bank 1
    movlw     b'xxxxxxx0'    ;(x= don't care = does not matter)
    movwf    TRISIO           ;the lowest bit will be an OUTPUT
    bcf         status, rp0     ;bank 0

2. Make the lowest bit of the output port = 1 (HIGH). This is done via the following instruction:

    bsf      GPIO,0


SETTING MORE THAN ONE BIT AT A TIME
Do not set more
than one bit at a time in the GPIO (in/out) port. The actual setting of a bit is very complex. The micro reads the value of the bit, modifies it, then writes the new value and the pin may be connected to a capacitor that take time to charge or allow the voltage on the pin to change and somewhere along the line, the result is not transferred to the result and the state of the pin does not change. To avoid this problem, do not create two instructions such as:

     
bsf      GPIO,0
     
bsf      GPIO,2

If you need to clear or set two or more output lines, perform the operation via a single instruction:

   
movlw   b'xxxxx1x1'
    movwf   GPIO

or perform:
 bsf      GPIO,0        bsf      GPIO,2    with other instructions between.

If you must perform the two operation in quick succession, y
ou need to know the state of all the outputs and include this in the value you are going to load into GPIO via movlw b'xxxxxxxx' etc. 

As can be seen from the above, the six lower bits of file 05 are connected to 6 pins of the chip and these connect the microprocessor to the outside world.  This file is like all the other files (from 20h to 5F - 64 files) as it can be operated-upon (incremented, decremented, shifted left or right, plus other operations). The only difference is the contents of file 05 can be exported to the outside world and the outside world can influence the file. When any of the bits of file 05 are configured as "out," the value of the bit will make the corresponding pin of the chip either HIGH or LOW. When it is "set" (=1), the pin will be HIGH. When it is "clear" (=0), the pin will be LOW.   
If you only want to change 2 or more bits and do not know the state of the other bits, you can use the following instructions. Only bits 0 and 4 will be toggled:

      movlw   b'0001 0001    ;only bits 0 and 4 will be toggled
      xorwf    gpio,f

To set 2 or more bits:

      movlw  b'0001 0001    ;only bits 0 and 4 will be set
      iorwf    gpio,f


MACRO'S
A MACRO is a piece of code that "gets inserted" into your program, by a program called an assembler, during the time when the program is ASSEMBLED. You only have to write a particular macro once, and it may be inserted 6 times into your program. Each macro must have an specific name (called a LABEL), so the assembler can find it.

I do not use Macros. They involve extra thinking and can take up extra space in your program.
But you will find some programmers use them and you need to know how they work.

A macro is like a sub-routine. It is written once and can be used many times in a program.
A macro has a LABEL just like any sub-routine. When you want to use a macro, the name of the macro is written on a new line in your program and the assembler adds the instruction(s) in the macro at the location where you have written the name of the macro.  If the macro consists of 5 lines and it is used 6 times, a total of 30 instructions will be added to your program.
The macro will be deleted from the assembled program and only the contents of the macro will appear 6 times.
The advantage of a macro is the slightly faster execution of the program as the microcontroller does not have to execute a call and return. The disadvantage is the extra lines of code. 

The reason for this article is to explain how a MACRO is prepared and the terms used.

The first line of a macro contains three terms:

LABEL       macro       PARAMETERS

LABEL can be any set of letters or numbers (some words cannot be used as they are used by the assembler and a label cannot begin with a number. Use "_"  or "." if numbers are required.

macro   tells the assembler that a macro is the next item in the program.

PARAMETERS   - a list of the files to be used with a comma between each.

Any number of lines of code can now be written. These will be any of the 33 PIC instructions.

The macro ends with:

endm      ;end of macro 

Example:

count      macro  Switch 
              incf    Switch,1      ;increment the Switch file
              btfss  Switch,6      ;test bit 6 in the switch file and if it is "1," miss next instruction
              goto   $+2            ;go to endm  ($+0 is this instruction, $+1 is next instruction)
              decf   Switch,1      ;decrement the Switch file and leave the result in the file.
              endm                    ;end of macro


MCLR PIN
Pin 4 can be configured as an "Input line" (GP3) OR "Master Clear."
To configure Pin 4 as MCLR   (also written as /MCLR  or /MCLRE ) the configuration bit setting is: _MCLRE_ON
When this pin is configured as /MCLRE, the pin resets the chip when it is taken LOW. But why waste a pin? Use the pin as an INPUT!
To configure Pin 4 as GP3, the configuration bit setting is: _MCLRE_OFF
This instruction tells the PIC to use its internal MCLR circuitry (to keep /MCLRE high), and leaves pin 4 free as an Input line. Note: MCLR pin (GP3) is INPUT ONLY.

MICROCHIP ICD PROGRAMMER
Microchip ICD programmer is sold in a round plastic case. If you have one of these and use long leads between the programmer and the chip you are "burning," add a 2k2 resistor to the clock line and 0v rail and a 2k2 to the data line and 0v rail to makes these lines LOW IMPEDANCE. We had enormous trouble programming a chip due to cross-talk between these two lines.

MPLAB IDE 
IDE stands for Integrated Development Environment and is part of MPLAB. MPLAB has two parts and the section we use is MPASM. The other section allows you to load your program into a window and look at how each register (file) is loaded or is currently holding bits (0's and 1's). It also has a single-stepping feature that increments thorough your program and lets you see what is happening. But this program is very complex and will cause lots of headaches, to get it up-and-running. We have kept things simple by showing you routines that work and you simple copy-and-paste.
  



MULTIPLYING AND DIVIDING
Numbers can be multiplied by 2 by shifting the file left with the instruction rlf  total,f  Before this instruction it is wise to clear the carry bit:  clrc
Numbers can be divided by 2 by shifting the file right with the instruction rrf  total,f  Before this instruction you must clear the carry bit:  clrc
You can also create a value of 0.75 by using the following instructions.
Suppose you have a file called loops and you want to reduce it to 75%:

                              ;you have a file called loops
    clrc                    ;clear carry before shifting
    rrf         loops,f    ;halve the value of loops
    clrc
    rrf         loops,w   ;halve the value of loops again and put into w
    addwf   loops,w    ;to get 0.75 of original

OSCILLATOR CALIBRATION VALUE
Calibration of the oscillator is only necessary when you need precise timing, as for serial communication. In most cases you will not have to worry about this.
To use the factory calibration value:



SetUp   org       0x00

            bsf       status, rp0     ;bank 1
            call       0x3FF           ;retrieve factory calibration value
            movwf   OSCCAL       ;update register with factory cal value
            bcf       status, rp0     ;bank 0

     
 

The oscillation calibration value can be changed from the value supplied in the chip by adding the following instructions to the end of your program, (BEFORE the "end" instruction of the program).


;****************************************************************
;* OSCCAL calibration value                                       * ;****************************************************************

      org       0x3ff
      retlw   0x20

      END
 

During the  programming of the chip, the above instruction will cause the burner to go to location 3FF and insert the value 20h as well as the instruction "return with the value 20h in W."
To create the maximum frequency, use: 3fh
Centre frequency = 20h
Minimum frequency = 00h
During the running of the program (when the chip is in the project), this value is put into the OSCCAL location, to adjust the frequency of the internal oscillator.
To get the micro to do this, the following instructions are added to your program:


;****************************************************************
;* Calibrating the internal oscillator                               * ;****************************************************************

       bsf       status,rp0     ;bank 1
       call      3ffh               ;get the calibration value
       movwf  OSCCAL       ;calibrate
       bcf       status,rp0     ;bank 0

 

The location of the oscillator calibration register is 90h. This is in Bank 1 and is identified in your program by writing: "OSCCAL" It is a 6-bit register, with values from 00h to 3fh.

If none of the above work, or if the calibration value is missing from location 3FF (for a PIC12F629), you can insert it by hand by carrying out the following:
1. This operation will erase the program in the chip and only install the osccal value, so make sure the program can be re-installed after this operation.
2. Connect the chip to a programmer and open the software on your desktop: PICkit 2 Programmer.
3. Under Tools  OSCCAL, select "Set Manually" from the drop-down window that appears on the right-hand side.
4. Scroll down to location 3FF in the Program Memory window and change location 3FF from 0000 or 3FFF to 3420.
5. Now you can re-install the program to the chip and the oscillator will operate a mid-position of its frequency-adjustment.
The PICkit 2 Programmer software will not burn any value placed in location 3FF, during a normal burn operation. You must select: Tools  OSCCAL,  "Set Manually" to burn the osccal value.
 

 

OTHER PROGRAMMER'S CODE
You will find some of the instructions and code in other people's programs very difficult to understand. You will need to know "high-level languages" to interpret the meaning of some of them.  We do not intend to teach any of these "complex sentences" or Pseudo Instructions. We will be showing you how to produce a program using just the 32 - 35 instructions needed to perform all the functions the microcontrollers are capable of.
Of course you can go one step higher and one step better by including extra complexity in your code but our intention is to start everyone at "level-zero" to "level-one" where you can produce a program to perform a reasonably simple task using the mnemonics of the instruction-set. 
Never use any instructions you do not fully understand.
However here is some explanations of instructions you will find in other people's programs:

ARITHMETIC OPERATORS AND  PRECEDENCE:    

 
OPERATOR Example
$ Current address goto $+3 ;goes to 3 locations down the program
goto  $   ;halts the micro
goto  $-4 ;goes to 4 locations up the program
( Left parenthesis 1 + ( d * 4)
) Right parenthesis (length + 1) * 256
! NOT (logical complement) if !  (a == b)
Negation (2's complement) 1 * length
~ Complement flags = ~ flags
* Multiply a = b * c
/ Divide a = b / c
% Modulus entry_len = tot_len % 16
+ Add tot_len  = entry_len * 8 + 1
Subtract entry_len = (tot 1) / 8
<< Left Shift flags = flags << 1
>> Right Shift flags = flags >> 1
>= Greater or equal if entry_idx >= num_entries
> Greater than if entry_idx > num_entries
< Less than if entry_idx < num_entries
<= Less or equal if entry_idx <= num_entries
== Equal to if entry_idx == num_entries
! = Not equal to if entry_idx ! = num_entries
& Bitwise AND flags = flags & ERROR_BIT
^ Bitwise EXclusive OR flags = flags ^ ERROR_BIT
| Bitwise Inclusive OR flags = flags | ERROR_BIT
&& Logical AND if (len == 512) && (b == c)
| | Logical OR if (len == 512) | | (b == c)
= Set equal to entry index = 0
+= Add to, set equal entry index += 1
= Subtract, set equal entry index = 1
*= Multiply, set equal entry index *= entry_length
/= Divide, set equal entry total  /= entry_length
%= Modulus, set equal entry index %= 8
<<= Left shift, set equal flags <<= 3
>>= Right shift, set equal flags >>= 3
&= AND, set equal flags &= ERROR_FLAG
| = Inclusive OR, set equal flags | = ERROR_FLAG
^ = EXclusive OR, set equal flags ^= ERROR_FLAG
++ Increment i ++
Decrement i  

Pseudo Instructions - these are additional Instructions understood by MPASM:

Mnemonic Description Equivalent Operation(s) Status
addcf
f,d
Add Carry to File
btfsc
incf
3,0
f,d
Z
adddcf
f,d
Add Digit Carry to File
btfsc
incf
3,1
f,d
Z
b
k
Branch
goto
k
-
bc
k
Branch on Carry
btfsc
goto
3,0
k
-
bdc
k
Branch on Digit Carry
btfsc
goto
3,1
k
-
bnc
k
Branch on No Carry
btfsc
goto
3,0
k
-
bndc
k
Branch on No Digit Carry
btfsc
goto
3,1
k
-
bnz
k
Branch on No Zero
btfsc
goto
3,2
k
-
bz
k
Branch on Zero
btfsc
goto
3,2
k
-
clrc
  Clear Carry
bcf
3,0
-
clrdc
  Clear Digit Carry
bcf
3,1
-
clrz
  Clear Zero
bcf
3,2
-
lcall
k
Long Call
bcf/bsf
bcf/bsf  
call
0x0A,3
0x0A,4
k
 
lgoto
k
Long GOTO
bcf/bsf  
bcf/bsf  
goto
0x0A,3
0x0A,4
k
 
movfw
f
Move File to W
movf
f,0
Z
negf
f,d
Negate File
comf
incf
f,1
f,d
Z
setc
  Set Carry
bsf
3,0
-
setdc
  Set Digit Carry
bsf
3,1
-
setz
  Set Zero
bsf
3,2
-
skpc
  Skip on Carry
btfss
3,0
-
skpdc
  Skip on Digit Carry
btfss
3,1
-
skpnc
  Skip on No Carry
btfsc
3,0
-
skpndc
  Skip on No Digit Carry
btfsc
3,1
-
skpnz
  Skip on Non Zero
btfsc
3,2
-
skpz
  Skip on Zero
btfss
3,2
-
subcf
f,d
Subtract Carry from File
btfsc
decf
3,0
f,d
Z
subdcf
f,d
Subtract Digit Carry from File
btfsc
decf
3,1
f,d
Z
tstf
f
Test File
movf
f,1
Z



 

PICkit 3 Debug Express
This is the name given to the latest PICkit programmer. When PICkit 3 is used in conjunction with MPLAB IDE  (Integrated Development Environment) the MPLAB IDE software will show you what is going on and this will help you in debugging your program.


READING AN INPUT LINE
When any of the bits of file 05 are configured as "input," (this is done via the TRISIO instruction) the HIGH or LOW on the pin of the chip (this HIGH or LOW will be created by something in the outside world making the line HIGH or LOW) will be read by the micro as a HIGH or LOW, (when the file is read via an instruction such as btfss GPIO,1 or btfsc GPIO,1 - test bit1 in file 05h, skip if set or test bit1 file 05h, skip if clear).
This "reading process" can also be done when the contents of file 05 (GPIO) is moved to W.  The instruction to do this is movf  05h,0 (movf    GPIO,0).  This instruction tells the micro to move the in/out port to the working register. The working register is called "W" and has the destination "0" - a file has the destination "1." The contents can also be shifted, incremented, plus other instructions.
Here are some instructions to read the input bit:
In most cases, the first bit (or line) to use in a program is pin 4 as this line is INPUT ONLY. It corresponds to GPIO,3.
Using the instructions from above, we have GPIO,3 as an INPUT and all other lines are OUTPUT.
We are looking for a HIGH on the input line.
To read the bit, use the following instructions:

    btfsc    GPIO,3    ;This will test the input bit and if it is LOW, the micro goes to movlw xx
    GOTO  PhaseA   ;This instruction takes the micro to a new sub-routine
    movlw  xx

If you don't know the state of some of the bits (or don't want to alter them - by mistake), you can use the XOR instruction.
For example, to turn ON bits 0, 1 and 2, the instructions can be:
bsf  GPIO,0     b'00000001'
bsf  GPIO,1     b'00000010'   
bsf  GPIO,2     b'00000100'
But this will result in only the third instruction being carried out. We mentioned above, not to use multiple bit-setting as it will fail to work.
The answer is to use the XOR instruction
Combine the 3 instructions to get: b'00000111'
movlw    07h
xorwf    GPIO,1
Only the three lowest outputs will go HIGH.
To turn OFF the three lowest outputs, repeat the same instructions:
movlw    07h
xorwf    GPIO,1
Only the three lowest outputs will go LOW.
Actually, the bits will TOGGLE.

 

RE-PROGRAMMING:
If you have trouble re-programming a chip, here are some possible solutions:
1. Put a 47k across the power rails to discharge ALL THE CELLS so the programmer can re-program the chip and prevent "failure to re-program" messages appearing on the screen, or:
2. If a chip is difficult to re-program, remove and replace it. The cells are discharged in this process.
Some chips are just difficult to program and you should buy a number of chips and only use those that are easy to program, when experimenting.

STACK 
The PIC12F629 has an 8-CALL stack. (8-level stack).
 

SUBTRACT - BE CAREFUL!
Suppose you
have a value from a table (it will be in w) and want to subtract (say) 10. The PIC12F629 micro does not have an instruction for this.
You cannot use: sublw  .10   
because the instruction subtracts w from .10  (decimal ten)
The instruction to use is: addlw   -.10 

TRIS
The TRIS register determines if each line is to be input or output.
It can be accessed by the following two lines of code:
   movlw    b'xx111111'   ;or b'xx000000' or any combination
   tris        gpio              ;
you do not need:
bsf  status, rp0 / bcf  status, rp0 to get to bank 1 then back to bank 0.

WEAK PULL-UP FEATURE
When any of the pins of a PIC12F629 or PIC16F628 are configured as inputs, you can turn on the weak pull-up feature by clearing bit 7 in the option_reg.
Note: GP3 does NOT have this feature. When-ever a pin is configured as an input it will have a weak pull-up of about 47k. This means you can have a switch connected between an input line
and 0v rail and when the switch is pressed, the input goes LOW.
 

 

 

 

P1(list of projects)   P3 The XOR Trick
 

 28/5/2010