Introduction to PIC Programming Using C: Programming a Super Simple LED Switch – Part 1
by Motbots in Circuits > Microcontrollers
467 Views, 6 Favorites, 0 Comments
Introduction to PIC Programming Using C: Programming a Super Simple LED Switch – Part 1

Disclosure: Motbots is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for us to earn commissions by linking to Amazon.com and affiliated sites.
Welcome! In the proceeding three part series, our goal is to learn how to program a PIC18F4525 microcontroller using the C programming language to control an LED with a couple of switches. It is my personal goal to help guide you to do this in a way that I learned from a terrific book I purchased some time ago of which you can observe for yourself at the Book Reference here.
The following is intended to be an enhancement to such pedagogical material that sometimes leaves more to be desired for the reader. It is the intention of the following to add more input to the learning material that is currently available, or currently unavailable, in the market today on learning how to program a PIC microcontroller using the C programming language.
This is Part 1: The Preliminaries
This will be a three part series. This is Part 1. I’ve divided this content into three parts because there was so much information to share with you that having it all on one page may have been overwhelming. I don’t want you to feel overwhelmed.
This should be a fun and exciting topic, not an intimidating one.
In Part 1, we’ll discuss some basics, like what a PICkit is, and why we need a PICkit. We’ll talk about the PIC18F4525 microcontroller and Microchip’s MPLAB software. I’ll show you how to install the MPLAB software and how to set it up. We’ll also discuss things we’ll need to know in C, and other important topics we’ll need to know.
In Part 2, we’ll get into building the prototype circuit, and go over things like the parts and tools we’ll need. We’ll also discuss about power supplies, and get into what a flowchart is and the need to use one. We’ll go over the schematic of this super simple LED switch project, and we’ll even go over all the pins we’ll be using on the PIC18F4525.
In Part 3, we’ll finish our discussion by going over the code, line-by-line, and how it works. We’ll even go over some common errors when trying to connect the PICkit device to the MPLAB IPE. In Part 3, we’ll be finishing up the project as a whole. We’ll then test the circuit and hopefully at the end have a working circuit.
I’ll try to teach you in a coherent, methodical, detailed, step-by-step process – doing it this way helps to ensure that you are understanding where information is coming from and how to understand it. I try not to leave you in the dark. This is the way that I believe all things should be taught, and I hope that I can perform this job successfully for you!
So, let’s get to it and begin the process of learning to do this cool project! But first, let’s begin with a few things we’ll need for this project.
Supplies



What We’ll Need
- PICkit 3 In-Circuit Debugger/Programmer: We’ll learn about this later.
- Universal Programmer Seat Board Adapter: We need this to easily make the connections of the pins of the PIC18F4525 microcontroller to the PICkit 3. This is one particular method to be able to communicate and transfer the compiled code we’ll write to the PIC microcontroller later. Using a universal programmer seat board adapter is easier than making connections between the two with jumper wires and a breadboard.
- Microchips’s MPLAB X v6.15: We’ll need these set of software tools to be able to create our code and compile it for the microcontroller in an integrated development environment (IDE), and to upload our code through to the PICkit 3 programmer, to our PIC microcontroller, via an integrated programming environment (IPE).
- PIC18F4525 Microcontroller (MCU): We will be using this 8-bit microcontroller to get us started in the world of embedded systems and learning how to program PIC microcontrollers. We’ll learn more about the PIC18F4525, later.
There will be some other components we’ll need for this project that we’ll get to later in Part 2, but before we get into that, let’s go over some preliminaries of what we need to setup and what we need to know before we jump into this project.
Details About Each Item We'll Need
We go over each of the items, in detail, on our website. The information provided there is key to understanding how this project will work, so it's highly recommended that you go check out the sections of the build that we do go over for each of these on the website here.
It's also recommended that you go ahead and download the datasheet for the PIC18F4525 microcontroller that we'll use for this project. Even if you don’t understand anything at this point, its good to glance over the first several pages of the datasheet to get a general understanding of the structure and information provided in a datasheet. YOU’LL NEED IT LATER, in Part 2.
DON’T WORRY! We’ll go step-by-step on how to set up the microcontroller and use it for the specific tasks we’ll be performing for our project. We’ll even go into the why we’re doing things too. I’ll try to make it as simple as possible for you! DON’T BE INTIMIDATED!
But Isn’t the PICkit 3 Outdated?
Yes, the PICkit 3 is now outdated and is not recommended for new designs and no new device support will be added to it as of June 1, 2019. As per Microchip’s website, it’s recommended to see about their new designs, like the MPLAB PICKit 5. Microchip’s MPLAB PICKit 4 reached its EOL (End of Life) back in September of 2023.
All that being said, I already had a PICkit 3 on-hand that I purchased a few years ago, and that’s why I’m using it here for this project. It will work just fine for what we’re going to do, so if you’ve got one already, then you’re good to go! Don’t feel that you need to rush out and purchase a new PICkit — that won’t be necessary — at least at the time of writing this it won’t be.
A PICkit 3 can still be found and purchased if you don’t have one. They’re much cheaper than the updated versions, but if you choose to use an updated version, like the PICkit 5, then you should be able to still follow along just fine.
I recommend that if you plan to purchase the PICkit 5, to buy it directly from Microchip, if they’re available. If not, buying from somewhere else can sometimes cost you much more. I also recommend that you check out Microchip’s page on the MPLAB PICkit 5 In-Circuit Debugger to help you get started in using one.
MPLAB X v6.15
To be able to use the outdated PICkit 3, we’ll need the use an older version of Microchip’s MPLAB software tools. I tried to use the most recent version of MPLAB (v6.25) as of date (May 2025) and was unable to get MPLAB IPE v6.25 to recognize my PICkit 3 programmer when plugged into my computer with its USB cable. It wouldn’t show up as a device to choose from the Select Tool menu.
I will be using MPLAB X v6.15, as the software for both creating and compiling the code for the PIC microcontroller using the MPLAB IDE, and to upload the hex file to the PIC microcontroller using the MPLAB IPE.
I’ll be using Microchip’s MPLAB version 6.15, since this is the version I originally had installed on my personal computer. This version was able to recognize the PICkit 3 programmer when plugged into my computer with its USB cable. It did show up as a device to choose from the Select Tool menu. You can download MPLAB X v6.15 from Microchip’s website here.
I did not try version 6.20, so I do not know if that particular version will recognize the PICkit 3 programmer. You can give it a shot, if you’d like. Otherwise, I’d just stick with version 6.15, for now.
How to Download MPLAB X V6.15 (Windows)
In this step we'll learn how to download MPLAB X v6.15 for Windows. We show the whole process, step-by-step with pictures, at our website for Part 1 of this project here.
What We Need to Know in C




The Preprocessor #include
#include is a preprocessing directive that runs before the actual compilation of code begins. It tells the compiler to use a standard or user-defined file in the program.
Basically, it’s just telling the compiler, “Hey, I want to include this file or library in my code here, to be able to use it later.” It’s almost always written at the beginning of the program and must include the hashtag or pound symbol (#) before the word include. For example, we could include the standard input/output library header in our code that supplies I/O functions that work with narrow characters, like this:
Main Function
The main function is a function named main that must be included in every C program. The main function is the entry point of a C program and is executed at the start of the program in a hosted environment, like an operating system.
We can think of main as being the main entrance or front door into our C code – without it, we have no way of getting in.
The syntax of the main function can be written in one of many forms. One such way is as follows:
In the above notation, the void return type means that the function does not return any information and the (void) in the parenthesis is a parameter that means that the function does not take any information either. The comment with the two forward slashes just lets us know that we write our code between the open and closed curly-brackets. The comment is ignored by the compiler.
While Loop
A while loop is a statement in a C program that executes a statement repeatedly until something causes the value of the expression to be equal to zero or false.
It’s like telling the program, “Hey, I’m gonna need you to keep doing this task for me while the statement I give you is true and stop doing the task when the statement is false. That would be great.”
For example, the following while loop will continue to loop through until the statement within it is false:
The while statement above evaluates the expression within the parenthesis, in this case a predefined variable within the code named counter. While the value of counter is less than 10, the statement is true and the loop will continue to execute.
Within the while loop is a statement that increments the value of counter by one each time the loop is executed. When counter is equal to 10 it makes the statement false and the code exits the while loop or the while loop ends.
We must be careful though, because it is easy to create an infinite loop. An infinite loop is an endless loop with no observable behavior in its statement or expression. An example of an endless loop is as follows:
Similar to the previous while loop we observed, the statement above evaluates the expression within the parenthesis, in this case a predefined variable within the code named counter. While the value of counter is less than 10, the statement is true and the loop will continue to execute.
Notice, however, that inside the while loop is a statement that decreases the value of counter by one each time the loop is executed. If the value of counter is always being decremented by one, then the value of counter will never be greater than 10, therefore always keeping the statement true. This means that the while loop will continue indefinitely or most likely crash your program.
We may sometimes want a loop to continue “forever” and add one at the end of our program, like the following:
For embedded systems, if we didn’t use an endless while loop at the end of a program, like the one above, the program would reach the end of its programming and terminate.
For an embedded system, like one that is meant to always determine if a button is pressed to either turn an LED on or off, would end prematurely if an endless while loop were not added to its programming. We would want to keep the program alive while listening to external interrupts, for example.
The argument of “1” inside the parenthesis in the while loop above, makes the statement true – actually it makes it always true. Therefore, the while loop above is an infinite loop, unless there is some external interrupt the while loop listens for within it.
The if-else Statement
The if-else statement is a conditional statement. It’s used in code only when some condition needs to be met for that part of the code to be executed. It’s like saying, “If the condition is true, then do this thing. Else, do that other thing.” For example:
The above statements first checks if the predefined variable height is greater than 0 and (&&) less than 60. If it is, then the print function prints to the terminal, “You must be 60 inches or taller to ride the roller coaster.”, and a new line (\n) is also printed to the terminal.
The next if statement checks for “out-of-bounds” values or “impossible” values for the ride. If the predefined variable height is less than 0 or (||) greater than 84, then the print function prints to the terminal, “You’re kidding, right?“, and a new line (\n). Else, then the print function prints to the terminal, “You are tall enough to ride this roller coaster!”, and a new line (\n).
The goto Statement and Labels
The goto statement in C allows the program to directly go to a certain point in the code, almost like jumping to some part of the code when needed to. You can think of the goto statement part of code as being like in a retro video game, where a side-scroll character finds a transport in the game to immediately go to another point in the level.
The goto statement gives the programmer more control over the program’s execution. Using a goto statement can be useful, at times, but is typically not recommended. Having goto statements in code, especially several of them, can make your code hard to read and understand, not only for yourself, but for others too. They’re also more difficult to maintain than using other ways to control the flow of code, like using your own functions and/or libraries.
An example of using a goto statement and labels is as follows:
We can see from the statements above that the code starts with an endless (infinite) while loop. For this particular application, an endless while loop is used for constantly listening for feedback from a user to press either of two momentary push-buttons to turn an LED on or off.
Such code is possibly used for an application that uses a microcontroller to control whether an LED is to be turned on or off, based on user input of pressing either of two separate momentary push-button switches.
A Start label begins the sequence of events within the while loop. If buttonOne is a logic ‘1’, or buttonOne is pressed, then a call to the On label is made within the loop to make the redLED a logic ‘1’, therefore, turning the red LED on.
If buttonTwo is pressed, or becomes a logic ‘1’, then a call to the Off label is made within the loop to make the redLED a logic ‘0’, therefore, turning the red LED off.
Now that we have some of the basics of C programming out of the way, let’s get to know about the hexadecimal number system. You may be asking at this point, “Huh?! Why are we learning about the hexadecimal number system?”
Good question. Well, to better understand some of the concepts of the code we’ll write later for our super simple LED switch project using a PIC microcontroller, we’ll want to familiarize ourselves with how we initialize certain registers we use from the PIC.
DON’T WORRY! We’ll get to what registers are and what kind we’ll use later on in our discussions. For now, let’s just continue on with the hexadecimal number system. Trust me, it’ll all make sense to you later… I hope.
Getting Familiar With the Hexadecimal Number System
When we start coding for the PIC18F4525, later on in our discussions, we’ll need to use what’s called special function registers (SFRs) for the PIC in our program. When initializing SFRs in code, we often use a hexadecimal format.
Sometimes we initialize these registers in code using a binary format. Sometimes we may need to make conversions between hexadecimal and binary, or from hexadecimal to decimal formats, or any other iteration between the formats.
We go over how to understand the conversions between binary-to-decimal, hexadecimal-to-decimal, and from hexadecimal-to-binary-to-decimal on our website for Part 1 of this series, here. It's highly recommended that you go check out these conversions and how they're done. It's all explained in a simple, easy-to-follow manner.
Conclusion
Okay, now that we have some of the preliminaries out of the way, we can proceed on to the fun stuff! In Part 2 of this Introduction to PIC Programming Using C: Programming a Super Simple LED Switch, we’ll actually get to start building our circuit on the breadboard!
Part 2 will start off with providing you the entire parts and tools list for this project, and move on to topics like power supplies, flowcharts and why we need them, we’ll go over the schematic for this project, along with going over the details of the pins we’ll be using on the PIC18F4525.
To see the rest of this series and complete this super fun project, you'll have to go to our Super Simple LED Switch Series - PIC Project page.
I hope that you’ve found the information here useful and really hope that this content has been helpful for you. I know that these preliminary steps of the process may seem tedious and boring to some, but as with all things new to learn, we must trudge through the tough stuff, so that we may gain a better understanding and experience on the subject matter. We don’t want to be left in the dark on things.
If you’ve found this information useful, please leave us a comment below. We’d love to hear from you. Help spread the word about Motbots, so that we may help others with similar interests as you in electronics and robotics. Thanks for your time here! We’ll see you in Part 2! Remember to keep at it and stay motivated.