PICmicro. PICmicro Advanced
The Program Counter (PC)
The program counter is an internal register/counter of the PIC, of 13 bit, and it contains the actual address of the program memory, that means that it point tl the instruction that has to be executed, then increases with one in order to point to the successive instruction.
If instead the instruction is a jump, the register is modified to point to the address wanted.
For being able to access, you will have to use two registers: PCL (8 bit) that represents the low part, and PCLATH (5 bit); We will see better how to use these registries a little later.
The programmers
To transfer the realized program from pc to PIC, it's absolutely necessary to have a programmer.
It can be auto-constructed, or bought; those last ones, there are lots of them either from MicroChip, or made by other companies.
The "home made" programmers are various too, but I will take in consideration only two most common types: the JDM (or LudiPipo, or Multipipo) and the ProPic2.
LudiPipo
It's very simple to be made and it's interfacing by the serial port, unfortunately it doesn't supports all the PIC, in particullar those with the final "A" in the name (ex: PIC16F84A) that need a voltage and a current that often the pc is not able to supply. Unfortunately if we don't have an external feeding, we will obtain a non-standard programmer, that sometimes could not function properly.

JDM programmer
ProPic2 Clone
The ProPic2 Clone (a simplified version of the ProPic2) is instead able to program many PICs, and it surely worth the trouble to make it; needs two feedings (12-14V and 5V), but the second one can be drawen from the first one using, for example, a LM7805.

ProPic2 Clone Programmer
Components:
7x Resistences by 4.7K, 1/4W
2x Transistor PNP BC327 or similar
1x Integrated 7407
1x DB-25 Connecter Male
1x LM7805
Two LED are optional on the Vcc and Vdd lines, in order to be sure that everything is functioning, with resistances of 330 and 1k ohm, while it is recommended the use of a 10k resistance for connecting the PIC to the Vpp programming voltage.
The Clock and Data lines that corresponds usually to the RB6 and RB7 pin, however it is sufficient to consult the datasheet of the PIC in order to be sure.
LM7805
L'LM7805 is a voltage limitter: applying it between IN and GND a 8-30V voltage, it will be obtained between the OUT and GND terminals a 5V voltage

The programmer in practice
I personally use with success the ProPic2, realized in an afternoon on a matrix board, but who is more equipped can realize even the PCB; in any case I recommend the use of a ZIF socket for an easier extraction of the PIC.
Moreover, inserting other sockets on the board (for example 28 and 40 pin), properly connected to the five lines (Vcc, Vdd, ground, Data and Clock), it can be programmed other models too, as PIC16F876 and 16F874, as well as the 8 pin serial memory.
Some programmers have the characteristic of using only one socket for programming many models, in our case is absolutely forbidden to use the same socket for models having different pin diagrams, it might broke irreparably the chip.
A little e-shopping
For who doesn't have time or the equipment (or the will) to realize the programmer, it is possible to buy it online, for example:
- Yapp 4 Lite
- PicBasic
- Programmer PIC 16F84
Whatever you'll buy, the important thing is that the programmer must have an external feeding in order to avoid unpleasant surprises.
The Software
Once the programmer is realized, let's see what we have to do to transfer the program from the pc to the PIC.
You can use various programs, the most common is IC-Prog, but I also recommend you the WinPIC800 and WinPIC. Those programs are offering the possibility to program many devices with different programmers, using a very simple and complete user interface.
First of all we must configure the program depending on the programmer that we have realized:
- Select as programmer "JDM Programmer" or "ProPic2 Programmer";
- If you are using the ProPic select the "Invert MCLR" and "Invert Vcc".
- Select the used port;
- Finally with Windows NT/2000/XP select the cell "Enable NT/2000 Drivers" in
Settings->Options->Misc;

The graphic interface is very simple: at the top there are present the icons that will serve us, in the two big areas there are the program-memory and the data-memory (EEPROM), at the right the chip's configuration.
It can be noticed in particular the Fuses, that are some necessary bit for the PIC's configuration; for our surposes they will be all deactivated, besides PWRT that introduces a little delay before the chip ignition, in such way to allow the feeder to become stable.
Finaly, here is the procedure to follow for programming a chip:
1) Select in the proper cell the chip model;
2) Open the .hex file generated by the compiler;
3) Modify the type of the oscilator;
4) Select the config-fuses;
5) Start programming pressing the "Program all" button;
MPLab
To write, compile and test the realized programs we will use the MPLab, a complete development environment for the PIC made by Microchip: it can be downloaded for free here.
I will not extend on the description of this program, but I will describe the main characteristics.
The IDE is integrated completely with the compiler, so through the Project menu you can start the compilation and you can observe the result in the proper window where it will appear the eventual errors.
Selecting the MPLab SIM in Debugger->Select Tool, it will be possible to make the step-by-step debugging of the developed application, and under the View entry are available different windows that are containing for example the Registries and the entire RAM, indispensable for monitoring the right functioning of the software.
Finaly with the Stimulus Controller you can interact with the integrated's pins, simulating the external signals to the PIC.
The instructions
The common instructions for all PIC families are 35 and are represented by mnemonic codes followed often by one or two operands.
Is good to keep in mind that, in the mnemonic code, often appear 3 letters that have precise meaning:
- l = literal: a numerical constant;
- w = working register: the accumulator register;
- f = file register: any register of the RAM.
We can classify the instructions in:
- instructions for data changing;
- logical-arithmetics instructions;
- jump instructions;
- general instructions;
General instructions
| CLR | clrf | f | Clear the f registry | f = 0 |
| clrw | Empty the accumulator | w = 0 | ||
| BCF | bcf | f,b | Reset the bit b of the f registry | bit clear f |
| BSF | bsf | f,d | Set to one the bit b of the f registry | bit set f |
| NOP | nop | No operation | no operation |
There are also other functions that we will see later and other, instead, outdated.
movlw B'01100010' ; w = 01100010b movwf 0x0C ; the register 0x0C = w bsf 0x0C,4 ; f = 01110010b, was set the 4 bit of the register 0x0C
Do not forget that the bits are from 0 to 7, so the bit 4, it isn't the forth, but the fifth.
Let's move the data
| MOV | movlw | k | Move a constant k in W | W = k |
| movwf | f | Move the contents of W in a registry f | f = W | |
| movf | f,d | If d=0 move the contents of the f registry in W, otherwise copy f in itself (it seems useless but it isn't!) |
[d] = f | |
| SWAP | swapf | f,d | swaps between them the two nibble of a registry; as the first the destination changes with d Example 0110 0011 => 0011 0110 |
With f=0 it is used the indirect address, in fact the INDF registry, put into the location 0, in reality it doesn't exist but allows to access to another registry; this last one it is decided modifying the FSR registry.
For example if I write in FSR the address of the port B (06h), reading or writing in INDF, in reality I am interacting with the PORTB registry.
movlw 0x05 ; w = 5 movwf 0x0C ; the registry at the address 0x0C now is 5 (00000101b) swapf 0x0C,1 ; the registry 0x0C it is swapped, therefor it is 01010000b movf 0x0C,0 ; w = f = 01010000b
Logical-Arithmetic instructions
| ADD | addwf | f,d | Adds to a registry f, the contents of W | [d] = f + W |
| addlw | k | Adds to W a costant k | W = W + k | |
| SUB | subwf | f,d | Substracts W from f | [d] = f - W |
| sublw | k | Substracts W from a costant k | W = k - W | |
| INC | incf | f,d | Increments with one the registry f | [d] = f + 1 |
| DEC | decf | f,d | Decrements with one the registry f | [d] = f -1 |
| AND | andwf | f,d | Executes the AND bit by bit between W and f | [d] = W AND f |
| andlw | k | Executes the AND bit by bit between W and a costant k | W = W AND k | |
| IOR | iorwf | f,d | Executes the OR inclusive between W and f | [d] = W OR f |
| iorlw | k | Executes the OR inclusive between W and a costant k | W = W OR k | |
| XOR | xorwf | f,d | Executes the OR exclusive between W and f | [d] = W XOR f |
| xorlw | k | Executes the OR esclusive between W and a costant k | W = W XOR k | |
| COM | comf | f,d | Executes the complement at one of f | [d] = not f |
| RLF | rlf | f,d | Rotates the byte in f towards left | [d] = f |
| RRF | rrf | f,d | Rotates the byte in f towards right | [d] = f >> 1 |
In the rotating instructions (rlf and rrf) the byte it is passed for the carry, that means that during a rotation towards left, the last bit doesn't become the first, but the last bit goes into carry and the carry takes the place of the first bit:

; w = not (f + 10) movlw 10 ; w = 10 addwf 0x0C,1 ; f = f + 10 comf 0x0C,0 ; w = not f
Jump instructions
| GOTO | goto | k | Jump to the address k | |
| CALL | call | k | Like goto but allows through the return instruction to turn back at the address of the call |
|
| BTF | btfss | f,b | Controls the bit b of the f registry, if it is 0 executes the next instruction, otherwise it jumps it. |
bit test f skip if set |
| btfsc | f,b | Controls the bit b of the f registry, if it is 1 executes the next instruction, otherwise it jumps it. |
bit test f skip if clear |
|
| DEC | decfsz | f,d | Decrements f, if results zero jumps the next instruction, otherwise it executes it. |
dec f skip if zero |
| INC | incfsz | f,d | Increments f, if results zero jumps the next instruction, otherwise it executes it. |
inc f skip if zero |
Every jump needs two machine cycles for being executed; instructions like btfss and decfsz are called "conditional jumps", instead others like call
and goto are called "unconditional jumps" because are not depending of other factors.
MPLab As you can see from the examples, in order to write the code assembly is necessary to follow some rules. The numbers can be expressed by the following three main notations: - decimal: the number will be written the way it is (ex: 10), if in the program header we insert the RADIX DEC directive, otherwise it is used the D'10' notation; - hexadecimal: the number must come after 0x or followed by h (ex: 0x0A or 0Ah); - binary: the number must come after B and included in apex (ex:B'00001010' or B'1010'); The code is divided in three columns: label, instructions and operands; to define them I advise you to use the TAB key from the keyboard. The labels are words that substituite an address of the program memory, are used in order to execute the jumps. All that comes after a ";" it is a comment and it is ignored by the compiler.
Instructions like decfsz and btfss, that are defined as jump instructions, in reality doesn't modify the PC, because if the jump is made, the next instruction it is simply replaced with a NOP.
btfss STATUS,C ; jumps if the carry is 1 goto Label1 ; goes to the address indicated by "Label1" .... goto End ; jumps to "End" Label1 .... End ....
- Ionela's blog
- 1333 reads





Programming Circuits
Thank you for the schematics and the explanation. Very well explained and clear.
I would like to point out that Microchip also has some free schematics for some of their programmers, even though they are much more complicated and expensive to build.
For you who use Linux, there is a good MPLab clone called PikLab. I love it.
PICmicro Advanced
Thanks for this valuable information. Regards!
----------------------------------------------
Kenali dan Kunjungi Objek Wisata di Pandeglang
Post new comment