Jan 04

Getting Started with PIC Microcontrollers

How to get started with microcontrollers is a very common question, and can be quite daunting for the newcomer. We will start right from the beginning, assuming almost no prior knowledge of the subject. Although we will probably cover other micros in later tutorials, we will start with the very popular PIC microcontroller range from Microchip.

What tools do I need to get started?

Luckily the answer to this question is “not very much”. At the minimum you will need:

  • A means of programming your microcontroller with the code you have written (generally known as “firmware”) There are hundreds of programmers to choose from out there, ranging from cheap “hobbyist type” to very expensive production programmers. For me, an important feature of the programmer is the ability to debug your code, and be able to be driven from within MPLAB or MPLABX – these are Microchips Integrated Development Environments (IDEs – we will cover these shortly)  Personally, I recommend either the PICkit3 or the ICD3, as these are the two I have experience with. Both have the features mentioned above, the only difference is that the ICD3 does a little more on the debugging side, programs faster and is a  “production programmer”. The is a comparison of their relative features here. If you don’t know what to start with, I’d go for the PICkit3.
  • A tool with which to organise your projects and write your code (an IDE) Microchip provides MPLAB and MPLABX for this purpose. MPLAB was the only IDE from Microchip for a long time, but recently MPLABX has been released and is the new IDE Microchip are focusing on. It’s based on Netbeans, and you get a feature packed tool somewhat like Eclipse/Visual Studio. I would pick MPLABX here, as it has many more features, plus MPLAB will probably be discontinued at some future point. If you are going to follow this tutorial right through to the end, then now would be good time to start downloading and installing MPLABX, and the XC8 compiler (free version – in the left column of the linked page) whilst you are reading the rest. Don’t worry if you have no components yet, if you wish you can use the simulator to run the code presented later on. For this all you need is your computer.
  • Something to test your microcontroller with. This could be a Development Board, or simply a breadboard you can layout yourself. On the dev board side, at $70 the PICkit3 starter kit is a pretty good choice; it’s on this page along with other starter kits. It comes with everything you need to get started, plus some tutorials on basic assembly programming. Olimex and other independent vendors also make some good dev boards. On the breadboard side, it’s a little more complex but more versatile, plus you will probably learn more this way. Which you choose depends on how much of a challenge you feel up to. We will cover the breadboard option here, but the discussion of coding and firmware will be just as relevant whichever option you take.
  • Optional – some prior knowledge of programming or electronics – particularly the C language as this is the language of choice for small micros. Assembler is well worth looking at, but nowadays memory is cheap, micros are fast and making firmware as small and efficient as possible is no longer as important as it used to be (many folk will disagree with this, and you will frequently see Assembly vs C discussions – my view is learn C for 99% of your firmware and use inline assembly when you need to, since they can be used together)

The breadboard route

First you need a breadboard (read link for how they work) and a few components to go with your microcontroller. A breadboard is used to make circuits up quickly and conveniently during prototyping. They all look something like this:

Secondly you need your PIC, and a few components to plug into it. For the PIC, we will choose something from the 16F series. Depending on what you can get hold of, this can be pretty much anything from that range. This is a common problem for newcomers, when they see a circuit on the ‘net which uses e.g. a PIC16F628, they assume that only that part will do. This is not the case – often, all that is involved in using code written for one PIC with another PIC is simply changing a couple of lines of code. Even jumping from say, the 16F series to the 18F/24F/32F series is not too difficult – this is the beauty of the C language: your code is portable, so you don’t have to write the same routine for each different microcontroller (this is one big advantage over using assembly)

I realise it can be difficult to get the newest parts in certain places, so here we will pick the PIC16F690, an oldish but reasonable part that should be widely available. If not, pick something similar – ideally source from places like Mouser, Digikey, Farnell, RS, etc; they have the latest stuff in stock at better prices than the smaller vendors. The downside is there is usually a minimum order for free delivery, but if you plan things you can order a few weeks worth of parts at once. I will mainly link to parts from Farnell here as that is my main source of components, but obviously you can get the same parts from many different places (eBay is good for cheap and cheerful parts, just watch out for dodgy vendors)

Anyway, here is a basic list of parts to start with (many of these are available in kits such as this one, so shop around a bit):

  • Breadboard – preferably select a decent size one with power tie points as shown above.
  • A load of jumper wires to connect your circuit together with. You can either buy some ready made ones such as these or these, or buy a roll of single core wire (I use 0.6mm which is equivalent to ~22.5AWG, but 22AWG or 20AWG should do fine) and cut your own.
  • A header to plug your programmer into during programing/debugging – this depends on which programmer you have. For the PICkit3 you need a simple 6-pin 2.54mm pitch header, whilst for an ICD3 you need either an RJ-11 (6-pin type), an RJ11 to 6-pin header adapter or this very convenient breadboard cable adapter.
  • Some passive components (“passive” roughly means things that don’t require power to perform their function, like resistors, capacitors, inductors)
  • Capacitors – 20 x 100nF ceramic capacitors (also listed as 0.1uF, which is the same value, 1nF is 1/1000th of a uF) – you will use a lot of these. 10pF, 15pF and 22pF ceramic (here are some options). 10uF, 100uF, 220uF, 470uF electrolytic types. There are also starter kits available which combine many of the common values.
  • Resistors – 10Ω, 47Ω, 220Ω, 1kΩ, 2.2kΩ, 10kΩ, 22kΩ, 47kΩ, 100kΩ, 470kΩ, 1MΩ metal film or carbon film type should be enough to get you started (or you can buy a kit of various standard values such as this, though you can often pay a lot more for the convenience of having them selected for you)
  • Crystals – the modern PICs have an internal oscillator (this is the thing that supplies the clock to the internal circuit) but it’s not as accurate timing wise as using an external crystal. Some applications require accurate timing, such as serial communications (e.g. RS232 or USB between PIC and PC) so you may want to grab some of these. Typical handy values are 32.768kHz, 4MHz, 8MHz, 12MHz, 20MHz.
  • LEDs – you need something to indicate events, an LED is a cheap and simple way of doing this. They come in many colours, shapes and sizes, but start off with some simple 5mm red LEDs.
  • General purpose transistors – you will need these for various things along the way, often for driving things that the PIC pins don’t have enough power to handle. There are two main types of transistor, bipolar and FET (Field Effect Transistor) Both have their uses. The choice of parts is overwhelming – some BC337-40 NPN, BC327 PNP, and some BS270 N-ch MOSFETs are a good start.
  • 7-segment displays, LCDs, Buzzers, Sensors, Motors – the list is endless once you get past the basics. Again, there are sensor kits available from places like Sparkfun, Adafruit, and other vendors if you want a basic selection handy for future use.

Okay, assuming you have (at least some of) the basic parts above, how do you wire things up on your breadboard? This is where the vendors datasheets and application notes (“app notes”) come in handy (you should read your first microcontroller datasheet from start to finish – all the information you need is there)

The datasheet, or a related app note will often have a minimum operational diagram. Googling a bit for things like (“PIC schematic”, “PIC16F starter kit schematic”, etc) brings up plenty of useful info. Using the “images” search option is often a good way to find what you are looking for.

Anyway, at the end of the “Low Pin Count Demo Board” app note, we find a very simple schematic, I have snipped out the relevant part of it below and taken the liberty of simplifying it a bit:

PIC16F690 Setup 2

We can see it’s very basic, apart from the PIC16F690 (U1) itself, there is only R1, C1 and P1 in addition. R1 is a 10kΩ resistor mentioned above, C1 is one of the 100nF ceramic capacitors (marked as 0.1uF – get used to this different marking of what is actually the same value, it happens all the time), and P1 is the 6-pin 2.54mm pitch header also mentioned. SW1 is optional, this can be used to reset the microcontroller, but if you have the programmer connected you can do this from within MPLAB (or disable the reset function entirely)

If you are not used to reading schematics, all the symbols marked the same are physically connected to each other (this saves making things messy by having to draw wires everywhere) For example, the little arrow with V+ above it is connected to all the other V+ symbols (V+ is your supply voltage, typically +5V for this PIC which can be supplied from your PICkit3 or ICD3 – not all programmers have this option though). Also the little downwards pointing triangle made from three horizontal lines means circuit ground, and these points are all connected together. Same again with the symbol marked RA3, the point over on the right is connected to pin 4 of the microcontroller which has the same symbol attached to it. 

Breadboarding the circuit

Okay, enough waffle, let’s actually make something happen. Since, we don’t have any display, the standard “Hello world” equivalent for microcontrollers is the LED blinking project, so we’ll go for this (boring I know, but it’s a start…)

This is the same schematic as the previous one (it’s good to get used to seeing schematics in different formats), but we have added an LEDs and resistor in for blinking purposes.


Now to setup the circuit on the breadboard, here is the result:


Ignore the yellow capacitor at the right middle (it’s part of another circuit on the same board) You can see the 100nF capacitor across the power pins, the anode of the LED connected to RB7, it’s cathode connected to the resistor then the resistor connects to the circuit ground at the top (pin 20 of the microcontroller) Also you can see the 10kΩ resistor between MCLR (pin 4) and the positive supply pin (Vcc – pin 1) The wires plugged into the board are the adapter wires from the ICD3 breadboard cable adapter previously mentioned above – the unlabelled blue wire plugged into the left hand side is the Vpp (programming voltage) connection .

Creating the project in MPLABX

Okay, now everything is setup, it’s time to write the code. Open up MPLABX and click on File->New Project (or Ctrl-Shift-N) This will bring up the following dialog box:


Select Standalone Project and click next. You will be presented with the dialog box below.We now need to select the part we will be using, so select Mid Range 8-bit MCUs and PIC16F690 (or if you are using another similar part 20-pin like the PIC16F685, PIC16F687, PIC16F689, etc, then select this instead) and click next.


You will now be asked to select an optional debug header (these parts do not have on chip debug capabilities) which we won’t be using, so just click next.

Now we get a dialog asking to select a tool for programming (e.g. a PICkit3, ICD3, etc) I have my ICD3 plugged in so I have selected this. Select your tool and click next.


Now we have to select the compiler we will be using, so we choose the XC8 compiler we downloaded before (if you didn’t, here’s the compiler page link again) You may have other compilers installed (as you can see I have) so make sure the XC8 compiler is highlighted and click next.


Now we finally give the project a name – I named it “LED Blink” and put it in a folder of the same name. Select “Set as main project” also (this just means it will be the active one of you have more than one project in your workspace) and click Finish:


Writing the code

Okay, we’re finally done setting up the project, now we can write the code. Under the “Projects” tab, right click on “Source Files” and select “C Main File”. This will create a basic template main file for you. You can rename it if you like from the default “newmain”, I called it “led_blink”.


You should now have something like this in the editor:


Don’t worry if you don’t understand the code, we will cover that in future tutorials. For now, let’s just get the LED blinking. Basically, all we need to add is a loop with two instructions to send a logic 1 to the LED pin, with a delay between them. Here is the updated code with this added:

/* * File: led_blink.c * Author: Oli Glaser * * Created on 02 January 2013, 06:59 */ // main include file - this contains all the "friendly names" // for the pins and peripherals #include <xc.h> // Turn the Watchdog Timer off #pragma config WDTE = OFF void delay(int d); // This is the prototype declaration for the Delay function int main(int argc, char** argv) { TRISBbits.TRISB7 = 0; // This sets pin RB7 to output while(1) // Infinite loop { PORTBbits.RB7 = 1; // Set RB7 pin to logic high (5V) delay(500); // Delay for roughly 500ms PORTBbits.RB7 = 0; // Set RB7 pin to logic low (0V) delay(500); // Delay for roughly 500ms } } // Delay routine void delay(int d) { int i; // Declare variable to be used in the loop while(d) // While d > 0 { i = 100; // set i to 100 for inner loop while(i) // while i > 0 { i--; // decrement i (e.g. i will equal 99, 98, 97,...) } d--; // decrement d } }


And that’s it, just copy the above code and replace the entire contents of the file with it. You will notice we changed the intial header files (e.g. #include stdio.h and stlib.h) and added #include <xc.h>. We also added a rather important line, the #pragma WDTE = OFF – this turns the watchdog timer off. The watchdog timer is a timer that needs to be reset before it times out otherwise it will reset your microcontroller. This can be useful in case the microcontroller hangs for whatever reason, but we don’t need it here as it adds complications.

We will cover more on these features in future tutorials. For now, you can experiment with the timing of the LED blink by passing different values to the delay routine. You could also try adding another LED to RB6 (hint – you need to make sure the pin is set to output)

I hope this is of use to a few people. If you spotted any mistakes, have any questions, ideas for improvement, suggestions for future tutorials, then leave a comment and I’ll do my best to answer promptly.


Skip to comment form

  1. Chandan

    Thanks for very nice tutorial, using xc8.

  2. Anonymous

    Very nice tutorial indeed! thanks

  3. Peter

    Very nice and straight forward, well explained & documented. For my first crawl in PIC programming this gave me understanding of the process. Good job! Thanks.

  4. Kashif Farhan

    i love PIC microcontroller
    so do i love PIC tutorials like this

    this PIC development board at kickstarter is my favourite

  5. Vincent van Rooijen

    Just what I was looking for: an easy to follow introduction to the PIC microcontroller without needing a Starter Kit.

    Thank you!

  6. Anonymous

    Very good PIC tutorials.

    In schematic, LED should connect to RB6(pin 11).

  7. Oli G

    Thanks for the heads up – fixed,

  8. BobbyS

    Thanks a bunch! This is a big help for a noob. This is exactly what I was looking for. Kudos to you for taking your time to write out a great tutorial.

  9. Anonymous

    Very nice tutorial, thank you!

    Just one thing that came to my mind: wouldn’t it be smarter to set i in the delay function to 99 instead of 100? That way, along with the d decrement, you get 100 instructions, i.e. one millisecond – or am I missing something here?

    1. Oli G

      Thanks for the encouragement 🙂
      You raise a good and valid point, however this was only meant to be a *very* rough delay routine so an instruction here or there wasn’t an issue (the while check takes up time also). The main objective was simplicity here for a first project tutorial.
      If you did need more accurate timing then you would need to take such things into account. There are a few options for improvement such as: writing the routine in assembly, using the timing tool in MPLABX to count the exact number of instructions per loop, using the timer peripheral, using the microchip library delay routines (which are well worth examining for tips on how to adjust for different clock speeds or PICs) etc. If you look at my other tutorial on the timer and interrupts, you will notice this very issue is discussed and the benefits of using the timer peripheral and interrupts for tighter timing and better use of CPU time are mentioned.

  10. Gary

    Thanks for the tutorial.
    Could you also give pointers or explain in detail on how to go with designing the circuit .. like why a resistor goes here and a capacitor overthere..?

    Thanks and Regards

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>