Category Archives: PIC Programming

In-circuit programming of PIC12F1822

In-circuit programming means that the PICKit3 programming tool is connected in parallel to the active circuit. This allows debugging and is very convenient in general since there’s no need to take the chip out and put it into the ICSP adaptor.

This is also useful for programming the chips when they are already mounted on a production board.

I will explain the connections and SW configuration in this post.

Wiring and connections

The following photo shows how the PICKit3 is connected to the chip.

PIC in-circuit connections

The PICKit3 header has six pins and pin number 1 is identified by an arrow as can be seen in the  next photo.

PICKit3 marking

The pins have the following functions:

1 – VPP/MCLR

2 – VDD

3 – VSS (Ground)

4 – ICSP data

5 – ICSP clock

6 – LVP (low voltage programming)

We use only the first five pins since we are not working in low voltage programming mode.

The table below shows where each PICKit3 pin is connected to the chip.

[table id=3 /]

The last connection is a 10K pull-up resistor connected from VSS to VPP – pin 4 – of the chip.

Configuring the MPLab IPE (Integrated Programming Environment)

Open the “Advanced mode” window in the Settings menu and select “Power” on the left pane. Make sure that VDD is correct (it is not correct in the screen shot below) and uncheck the “Power target circuit from tool” check box, so that the chip will be powered from the power supply. The reason is that the tool can not provide enough power for programming when it is in-circuit.

PICKit3 settings

 

Possible problems

I encountered the following errors before I found how to set this up correctly:

“Too much power drawn on VDD” – the VDD and VSS are not connected to the power supply but instead draw power from the PICKit3.

 

PIC LED Controller – Stage 1

My first PIC project is a LED controller (henceforth referred to as “LC”) for my Quadcopter 1. The LC will receive commands over a RC channel and control four high intensity LEDs that I will connect to the underside of the arms of the quadcopter. I will describe the features of the LC in a separate post. This post describes the first stage of programming the LC.

In this stage I wrote code that allows me to control any number of LEDs (well, in practice I can attach only four LEDs to the PIC12F1822) by defining different properties for each LED. The code is object-oriented in the sense that the behaviour of each LED is defined in an instance of a struct (=an object) and functions operate on these objects. I considered implementing a full object oriented model in which the functions are also included in the struct, but I FEEL that the overhead of this approach is too much for the tiny PIC controller and the inefficient compiler (the free XC8) that I use.

The following video shows the LC in use with two LEDs that blink at a different rate. The yellow LED blinks three times and then waits while the green LED blinks five times and waits. These two LEDs can be used as indicators to the internal state of the LC which has a major state (yellow LED) and a sub-state (green Led).

So let’s describe the code.

The application consists of three files:

  • Main function with the main loop
  • LED Controller header file
  • LED Controller implementation

Main

I will start with the main function because it shows how the LC code is used.

[file]http://www.qcptr.com/code-snippets/led-controller-stage-1/main.c[/file]

Main.c starts with setting up the configuration bits. Then the ISR counts the number of times Timer0 overflows where each overflow happens every 0.25 of a millisecond. The calculation is as follows:

  1. Timer 0 prescaler (PSA) is set to 8 which means that the timer counts at a rate of 1Mhz
  2. On each overflow TMR0 is set to 6 so it counts 250 ticks before it overflows again.

Then the main function starts with initialising the ports and defining the LEDConfig instances for the two LEDs. Finally the main loop starts. After every 4 overflows of Timer 0 (which are more or less equivalent to 1ms) the main loop calls the HandleLEDs function that updates the state of the LEDs.

Note that main needs only instantiate the LEDConfig structs, pass them to the LC and then notify the LC once every 1ms.

LED Controller header file

The header file defines the “blink interval” and “off interval”, the LEDConfig struct and declares the functions that operate on instances of LEDConfig. The “blink” and “off” intervals specify the amount of time a LED is on or off while blinking and the amount of time it is off between bursts of blinking.

[file]http://www.qcptr.com/code-snippets/led-controller-stage-1/ledcontrol.h[/file]

LED Control C file

The C file manages the array of LEDConfig structs so that the user of this code (i.e. the main function in this example) needs only create these structs and pass them to the LC. Main must also notify the LED controller of every “tick” of the clock and the LC takes care of everything else.

[file]http://www.qcptr.com/code-snippets/led-controller-stage-1/ledcontrol1.c[/file]

Credits

I found this site somewhat useful to understand how Timer 0 should be used.

 

My first PIC project

My first PIC project is very simple, kind of a PIC “hello world” program. My program reads the state of a push button and turns on a LED if the button is pressed.

This is the circuit:

test1schematic

And this is how it looks on the breadboard:

PIC Test 1 Breadboard

Note that the 10K Ohm pull up resistor is not on the breadboard and the button is connected to negative. The reason for this is that the PIC12F1822 (and I assume all other PICs) has an internal pull up resistor. The pull up resistor connects the input pin (called RA3) to the +5V VDD pin and keeps it high. When the button is pressed it switches the input pin to low. Therefore the program turns the output pin (RA0) to high when the input (RA3) is low.

Page 3 of the data sheet contains a table that describes all the pins of the PIC12F1822. Note that all the input/output pins have internal pull ups.

This is the program:

#include <xc.h>

// CONFIG1

#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)

#pragma config WDTE = OFF // Watchdog Timer Enable 
#pragma config PWRTE = ON // Power-up Timer Enable 
#pragma config MCLRE = OFF // MCLR Pin Function Select 
#pragma config CP = ON // Flash Program Memory Code Protection 
#pragma config CPD = ON // Data Memory Code Protection 
#pragma config BOREN = ON // Brown-out Reset Enable 
#pragma config CLKOUTEN = OFF // Clock Out Enable 
#pragma config IESO = ON // Internal/External Switchover 
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable 

// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection 
#pragma config PLLEN = ON // PLL Enable 
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (
#pragma config BORV = HI // Brown-out Reset Voltage Selection 
#pragma config LVP = OFF // Low-Voltage Programming Enable 

void main()
{
    TRISA3 = 1;
    TRISA0 = 0;

    OPTION_REG = OPTION_REG & 0x7f;
    WPUA3 = 1;

    PORTAbits.RA0 = 0;

    while (1) {
        if (PORTAbits.RA3 == 0)
            PORTAbits.RA0 = 1;
        else
            PORTAbits.RA0 = 0;
    }
}

I will not describe all the configuration bits at this stage. Note only that I disabled the watchdog because I still don’t know how to keep it alive. I will definitely turn it on in one of the next projects.

Note also the OPTION_REG assignment and the WPUA3 assignment. These lines turn on the internal pull up resistor on pin RA3.

This small program gave me an opportunity to understand what “pull up” is about and I summarise it in the following short video. The video starts with the internal pull up disabled and without an external pull up resistor. You can see that the LED is on even when the button is open. Additionally, the voltage on RA3 is affected by moving my finger near it and we see that the LED flickers.

Then I place a 10K Ohm resistor between RA3 and +5v. This immediately stabilises the LED and it goes on only when the button is pressed.

Next I remove the resistor and replace the chip with another one that runs the program with the internal pull up enabled on pin RA3. In this case the LED behaves as expected and lights up only when the button is pressed.

Here is the video:

PIC – Motivation and Preparation

Learning to program and work with micro controllers is the fundamental step towards developing applications for quadcopters. Therefore I am going to spend some time on micro controller programming and share my new knowledge with my dear readers.

This first post will describe the micro controller that I chose to use and the preparation steps – what to buy and how to set it up.

I chose to work with the Microchip family of PIC micro controllers.

Why use Microchip PIC controllers?

I decided to accept my friend’s advice and start using PICs from the beginning. The main reasons for using PICs and not other controllers are:

  1. Price – they are cheaper then Atmel chips for example
  2. They exist for many years and are very reliable and stable
  3. Variety – there is a large number of controllers with different capabilities, so it should be possible to find a cost-effective controller for every application. Or, as Microchips says on their site: “Microchip provides solutions for the entire performance range of 8-bit, 16-bit, and 32-bit microcontrollers, with a powerful architecture, flexible memory technologies, comprehensive easy-to-use development tools, complete technical documentation and post design in-support”. And no, I don’t work for Microchip (but maybe I’ll ask them to put a link to my blog from their site).
  4. Tomer, my friend, uses PICs for his projects, so I can learn from him and ask for help when I get stuck. I think that at the end, this is the main reason for choosing PICs.

Preparations

We have to buy a few things and set them up before writing the first line of code for a PIC.

Stuff to buy

First of all you should decide which PIC micro controller you want to use and then buy one or two. You can get them from many sites on the net and in real stores. I decided to accept Tomer’s advice and use the PIC12F1822 just because it is cheap, simple and sufficient for my first project (a LED controller for my quadcopter) and … Tomer gave me two of them so I didn’t have to buy any.

The full shopping list is:

[table id=2 /]

Regarding the PICKit 3 programmer – Instead of buying the original Microchip product I bought a clone from eBay. It is cheaper but my MAC OS on two computers (Yosemite – running on a Mac Mini (mid 2011) and on a Macbook Pro 15 mid 2012) does not recognise it. I will describe a bad workaround below.

Tomer suggests putting the chip in a socket and moving it around inside the socket.

This is how this stuff looks like:

PIC Programming kit

Installation and set up

Download and install the Microchip MPLab X IDE and the XC 8 compiler. Both are free.

IDE: http://www.microchip.com/pagehandler/en-us/family/mplabx/

Compiler: http://www.microchip.com/pagehandler/en_us/devtools/mplabxc/

Download the data sheet for the PIC and start reading it. It is a fascinating ~400-page reading. In fact, you don’t have to read it all at once, but at least find the locations of the following pins of the chip that you need for programming:

  • VDD – power
  • VSS – ground
  • MCLR – I’m still figuring out what this is
  • ICSPDAT – programming data
  • ICSPCLK – programming clock

Download the PICKit3 user’s guide from here.

The IDE installer will offer to install the IDE and the IPE – the Integrated Programming Environment. Install both.

Connect the 6-wire programming connector to the PICKit 3 module (the red box) and connect the PICKit3 to the USB port of your PC.

Place the chip into the ICSP adapter and connect 5 wires of the programming connector to the corresponding pins of the adapter. The pinout of the programming interface are listed in page 10 of the PICKit3 user’s guide.

Then start the IPE – the integrated programming environment. Here is a screen shot of my IPE.

IPE screen shot

You should select the correct chip (Device) by first selecting the family and then selecting the chip from the drop-down menu. In the “Tool” field you should see the serial number of your PICKit 3. As you can see, the program does not identify my fake PICKit 3 so it says “Default_pk3”. This is not good but I have a work around for now and I intend to find the reason later.

Press on “connect” and it should connect (unlike my IPE above).

Once it is connected you are ready to go.

Workaround for using my clone PICKit3 on a MAC

The only workaround I found so far is to run a virtual Windows 7 guest on VirtualBox on my Mac. I place the project in a folder that is permanently shared with the guest machine. I run the IDE on the MAC and the IPE on the virtual Windows machine. I hope to find a solution before I need to use the debugger features of the PICKit 3.