Getting Started with MPLAB XC8 Compiler – LED Blinking

Getting Started with MPLAB XC8 Compiler – LED Blinking

In this tutorial we will learn How to Blink an LED with PIC Microcontroller using MPAB XC8 Compiler. Recently Microchip released a series of development tools including MPLAB X IDE and MPAB XC Compilers. MPLAB X IDE is a software that runs on a computer intended to develop applications for Microchip’s Microcontrollers and Digital Signal Controllers. It can be used with Windows, Mac and Linux Operating Systems. It is called an Integrated Development Environment as it provides comprehensive facilities to the developers. Unlike previous  versions of MPLAB, MPLAB X IDE is based on open source NetBeans IDE by Oracle.

MPLAB XC Compilers are general solutions for all Microchip PIC Microcontrollers and it can be used for any Project. It replaces all MPLAB C and Hi-Tech C compilers. Microchip recommends every developers to use MPLAB XC Compilers. These compilers integrates with MPLAB X IDE to provide full graphics front end.

In this example project we will blink an LED using PIC 16F877A Microcontroller. For that we will use MPLAB X IDE and MPLAB XC8 Compiler. You can download MPLAB X IDE and XC8 Compiler from the respective pages.

You should install Java before installing MPLAB X.

  • Download and Install MPLAB X IDE.
  • Download and Install MPLAB XC8 Compiler.
  • Open MPLAB X IDE.


  • Click on File >> New Project
New Project - Step 1

New Project – Step 1

  • Select Microchip Embedded >> Standalone Project
  • Click Next
New Project - Step 2

New Project – Step 2

  • Select Family and Device.
  • Click Next
New Project - Step 3

New Project – Step 3

  • Select your Hardware Tool. Don’t worry if your programmer is not supported. You can directly burn the hex file after building the project.
  • Click Next
New Project - Step 4

New Project – Step 4

  • Select the Compiler XC8.
  • Click Next
New Project - Step 5

New Project – Step 5

  • Give Project Name, Project Location etc.
  • Click Finish
New Project Wizard Completed

New Project Wizard Completed

  • Right Click on the Source Files in the Project Tree.
Adding a Source File

Adding a Source File

  • Select New >> C Main File
  • Provide Name and Location of the file
Name and Location - New C Main File

Name and Location – New C Main File

  • New Source file is created, you can add code here.
New Source File Created

New Source File Created

MPLAB XC8 Programming

  • Input Outputs pins of a PIC Microcontroller is divided into different PORTS containing a group of GPIO (General Purpose Input Output) pins.
  • Since PIC 16F877A is an 8-bit microcontroller, each PORT contains 8 Input Output pins.
  • In 16F Microcontrollers, each port is associated with two registers : TRIS and PORT. Eg : TRISB, PORTB, TRISD, PORTD.
  • TRIS stands for Tri-State, it determines the direction of each GPIO pins. Logic 1 at a particular bit of TRIS register makes the corresponding pin Input while Logic 0 at a particular bit makes the corresponding pin Output.
  • All Input pins will be in Hi-Impedance state.
  • PORT Register is used to Read Data from or Write Data to Input Output pins.
  • For an Output pin (TRIS bit is 0), Logic 1 at PORT register makes the corresponding pin Logic High (VDD) and Logic 0 at PORT register makes the corresponding pin Logic Low (VSS).
  • Since PIC 16F877A is a 5V device, VDD = 5V and VSS = 0V.
  • PORT Read operation reads the Physical State (actual Voltage Level) of IO pins. If an IO pin is at a potential near to VDD, corresponding PORT bit will be Logic 1 and if it at a potential near to VSS, corresponding PORT bit will be Logic 0.
PORT and TRIS Register in PIC Microcontroller

PORT and TRIS Register in PIC Microcontroller

Writing Registers

You can write to PORT and TRIS Registers entirely or bit by bit.

Writing Bit by Bit :

TRISC0 = 1; //Makes 0th bit of PORTC Input
TRISC5 = 0; //Makes 5th bit of PORTC Output
RB3 = 1; //Makes 3ed bit of PORTB at Logic High
RB7 = 0; //Makes 7th bit of PORTB at Logic Low

Writing Entire Register

You should be familiar with following C Programming concepts.

  • A number with a prefix ‘0b’ indicates a binary number.
  • A number with a prefix ‘0’ indicates an octal number.
  • A number with a prefix ‘0x’ indicates a hexadecimal number.
  • A number without prefix is a decimal number.

Let’s see some examples…

Decimal Binary Octal Hexadecimal
0 0b00000000 00 0x00
1 0b00000001 01 0x01
128 0b10000000 0200 0x80
255 0b11111111 0377 0xFF
PORTB = 0xFF; //Makes all pins of PORTB Logic High
TRISC = 0x00; //Makes all pins of TRISC Output
PORTD = 128; //Makes 7th bit of PORTD Logic High

Code – LED Blinking

#define _XTAL_FREQ 8000000

#include <xc.h>

#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

int main()
  TRISB0 = 0; //RB0 as Output PIN
    RB0 = 1;  // LED ON
    __delay_ms(1000); // 1 Second Delay
    RB0 = 0;  // LED OFF
    __delay_ms(1000); // 1 Second Delay
  return 0;

First statement #define _XTAL_FREQ 8000000 defines the clock frequency of the microcontroller which is used to calculate delays in __delay_ms() function. Second statement #include <xc.h> includes the header file xc.h which contains the definition of __delay_ms() function and TRIS, PORT registers.

Next is #pragma config directives, which is used to tell the compiler to set Configuration Bits of PIC Microcontroller. You can generate it using the MPLAB IDE as following.

  • Go to Window >> PIC Memory Views >> Configuration Bits
PIC Memory Views - Configuration Bits

PIC Memory Views – Configuration Bits

  • You can select the configuration at the bottom of the IDE as shown below
PIC Memory Views - Configuration Bits

PIC Memory Views – Configuration Bits

  • Click Generate Source Code to Output
Generated Configuration Bits Source

Generated Configuration Bits Source

  • You can simple copy paste this generated code to code editor.
  • Then enter the remaining code for the blinking of LED.
  • Build the Project
Building the Project

Building the Project

  • Hex File will be generated in the location Your Project Folder >> dist >> default >> production

Circuit Diagram

Blinking LED using PIC Microcontroller - Circuit Diagram

Blinking LED using PIC Microcontroller – Circuit Diagram

VDD and VSS of the PIC Microcontroller is connected to +5V and GND respectively. 8MHz crystal oscillator is used to provide necessary clock for the operation of the microcontroller. 22pF capacitors are used to stabilize the clock generated by crystal oscillator. An LED is connected to RBO (Pin 33) via a 470Ω resistor to limit the current.

Download Here

You can download entire project files here…

Share this post

Comments (44)

  • Mohan

    My MPLABX is quite slow it takes arround 10-20 minutes just to open why.?

    September 6, 2014 at 5:50 pm
  • Ligo George

    I don’t know… Post this question in Microchip’s forum…
    It might be the problem with you PC.

    September 9, 2014 at 4:32 pm
  • Sathwik Sai Pokkula

    What changes to be done if it is pic24f family?? … In both the configuration part and code part

    October 19, 2014 at 11:38 pm
  • Ligo George

    Just change RB0 to LATB0..
    You can edit the configuration in in MPLAB IDE itself .. and copy the settings to your code. .as described above..

    October 22, 2014 at 9:12 am
  • Muhammad Zaki

    hi george..i just put #include and suddenly its shows like this,can u help me whats wrong with it

    October 29, 2014 at 6:28 pm
  • Ligo George

    1. Go to “Run” in the dropdown menue

    2. Choose “Set project configuration”

    3. Choose “Customize”

    4. When the window opens, choose “XC8 compiler” under the “XC8 global options” in the categories window.

    5. Ensure that “Preprocessing and messages” is selected in the “Option categories” drop down menu.

    6. In the “Include directories” section add the directory that the plib.h header refers to ( c:/program files (x86)/microchip/xc8/v1.xx/include/plib). Once that is done, it will not give the error flag.

    October 31, 2014 at 5:05 pm
  • Shamim

    I am a novice of this section but I am trying hard and soul to grasp this hobby.

    Sir, you use 8 line (i.e, 8 statements in configuration section) but when I go to the configuration menu in the MPLab X IDE there are huge things to be configured !! I totally thundered. Is there any specific options corresponding to my code only which configuration is enough to run my code ?????? PLZ ans..

    April 23, 2015 at 3:06 pm
  • Ligo George

    It will depend on the PIC you are using… Above tutorial uses PIC 16F877A

    April 27, 2015 at 10:20 pm
  • Qasim Alkhairi

    hi Ligo can you help me how i edit or rebuild the code with MPLAB software i have also XC8 & HI-TECH C compiler but i did not edit or rebuild the code………….

    April 28, 2015 at 4:34 pm
  • Ligo George

    Hi, I don’t understand what you are saying.
    You can build above code with XC8 compiler with MPLAB X IDE.

    May 6, 2015 at 9:58 am
  • Qasim Alkhairi

    ok thnx………..

    May 6, 2015 at 11:44 am
  • ali

    امان از فارسی نوشتنت

    May 30, 2015 at 10:02 am
  • manjula

    Plz sir…can u help me.I want 16F628a micro controller PORTB+PORTA shift Assemble and C tutorial…

    June 23, 2015 at 12:32 am
  • Bela Cseke

    Hi Ligo. Can you tell me please, is it a big difference between HiTech C and XC8? I mean a have a HiTech source code and I would like to transfer to XC8 as my device (PIC18F26K22) not supported by HiTech C.

    September 18, 2015 at 7:33 pm
  • Ligo George

    Hi-Tech C is the old compiler. Microchip stopped the support for Hi-Tech C.
    The latest one is X8.

    October 3, 2015 at 3:26 pm
  • Hrishikesh Kale

    hello LIGO,

    May i have your Email-ID

    1.) I Am using Pic18F4520 Controller.

    i have made my mclr pin positve i.e +5V applied to it.

    also used crystal of 10Mhz hence capacitor of 15 pF. and in config had selected oscilator mode as HS.

    I have wrote a program to blink led but it’s not working practically but in simulation it’s perfectly fine.

    2.)One more i found that i have to insert a small wire at pin NO. RB5 the on the PIC DEM 2 Plus (old) it’s working fine

    Plz help me..

    i am attaching my code.

    My main Program:




    #include “_config.h”


    void delay(unsigned char x)


    for(unsigned char i=0;i<=x;i++)

    for(unsigned char j=0;j<=135;j++);


    void main()




    TRISB= 0;

    LATB = 0xFF;


    //LATB = 0xF0;


    LATB = 0x00;


    //LATB = 0x0F;




    Config File:


    // #pragma config statements should precede project file includes.

    // Use project enums instead of #define for ON and OFF.

    // CONFIG1H

    #pragma config OSC = HS // Oscillator Selection bits (HS oscillator)

    #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)

    #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

    // CONFIG2L

    #pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)

    #pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)

    #pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)

    // CONFIG2H

    #pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))

    #pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)

    // CONFIG3H

    #pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)

    #pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB pins are configured as analog input channels on Reset)

    #pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)

    #pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

    // CONFIG4L

    #pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)

    #pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)

    #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

    // CONFIG5L

    #pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)

    #pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)

    #pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)

    #pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

    // CONFIG5H

    #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)

    #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

    // CONFIG6L

    #pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)

    #pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)

    #pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)

    #pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

    // CONFIG6H

    #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)

    #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)

    #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

    // CONFIG7L

    #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)

    #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)

    #pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)

    #pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

    // CONFIG7H

    #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

    [email protected]

    October 10, 2015 at 1:07 am
  • Ligo George

    Check the configuration bits in the program. Turn OFF LVP etc.

    November 21, 2015 at 1:14 pm
  • Bobby S

    Thanks for this tutorial, this works really well. How can i use this block of code 3 times in a program? I want different delay times that I can input from a switch. I cannot figure out how to activate only one at a time.

    December 30, 2015 at 3:51 am
  • Ligo George

    You can simply use if() control statements.

    December 30, 2015 at 8:45 am
  • Bobby S

    Thank you for the information I will give that a try.

    December 31, 2015 at 2:13 am
  • Isaias Leal

    First than all, thank you for the information. But I have a problem and I wonder if you could help me. When I try to select the compiler it doesn’t say nothing about the XC8 and I want to know why. Did I make a mistake in the installation? or maybe is the new version? How should I proceed?

    Thanks for your attention.

    March 1, 2016 at 11:27 am
  • Isaias Leal

    This is the image

    March 1, 2016 at 11:28 am
  • Aravind NA

    sir i delay time error shows while code has been typed….pls help me

    April 1, 2016 at 11:48 am
  • Aravind NA

    like this…..

    April 1, 2016 at 11:50 am
  • Fed Ped

    you forgot “include “

    April 10, 2016 at 12:59 am
  • Ligo George

    What error ?

    April 15, 2016 at 8:04 am
  • Ligo George

    Image not clear. Please post the error.

    April 15, 2016 at 8:05 am
  • Ligo George

    If the error is inline delay argument too large, you need to make a user defined function and call it.

    like this :

    void Delay10(unsigned a)

    April 15, 2016 at 8:20 am
  • Ferg

    Hi Ligo, great website I really enjoy your work. Just wondering have you ever managed to get the WDT of a PIC16F690 to work using XC8 compiler. Regards, Ferg.

    November 1, 2016 at 2:21 am
  • Alexander Erakhtin

    I’m trying some basic stuff on the PIC18f4455 and for some reason I can’t change the voltage level on the pins. Code compiles, downloads into the chip, but that’s it. No blinky, no nothing… Any ideas? ADC is turned off, btw.

    November 20, 2016 at 1:18 am
  • Ligo George

    I haven’t yet used 16F690. But watchdog timer will work fine without any problems.

    Kindly use our forums ( ) for asking doubts outside the scope of above article.

    November 27, 2016 at 2:31 pm
  • Ligo George

    Kindly use our forums ( ) and put your complete code there.

    November 27, 2016 at 2:41 pm
  • keneni kane

    I have downloaded and installed both IDE and the Compiler (MPLAB X IDE and MPLAB XC8 Compiler). but when I try to create a new project, it doesn’t let me choose the XC8 Compiler. However, I have an other Compiler(mpasm) but I don’t know how to access it (it’s header file). most of the time I’m using pic.h to program PIC16F877. but now it’s not working for me. Please help.

    February 22, 2017 at 4:17 pm
  • Arnav

    you could also use this , for (int i = 0;i <20;i ++) _delay_ms(50);
    As 20 x 50 = 1000 ms which is one second

    February 22, 2017 at 6:15 pm
  • Amy Martin

    I downloaded the project files you had given here. But I cannot open it in my MPLAB X. I actually needed help in writing the header file. xc.h. I’m using PIC16F15356 for my project

    April 4, 2017 at 3:50 pm
  • wildansn

    what is the changes when I use dsPIC30F2020 instead?

    April 28, 2017 at 11:43 am
  • Vishnu satheesan k

    Hi Ligo George, thank you for this content,,,,i brought your product(programmer) from eBay and followed all these steps exactly,but i am getting this error(red under line) “cannot find include file “.When i build this program,the program build successfully,but led is not blinking.(MPLAB X IDE V3.60,electrosome programmer,pic16f877a,pickit2 are used here). Please help.

    May 30, 2017 at 4:06 pm
  • Winston Navin Dias

    what is the use #pragma,,, i’m using mikro c , in that i’m not having anything like this #pragma y, and in mikro c how the configuration bits are set?

    September 5, 2017 at 11:57 pm
  • Prabaharan

    I need a pic16f877a in mplab x ide program of when switch is pressed led on and again switch is pressed led off.

    September 26, 2017 at 12:04 pm
  • Prabaharan

    I need a pic16F877A in mplab x ide program of when switch is pressed led on and again switch is pressed led off.

    September 26, 2017 at 12:06 pm
  • Witek Widzew

    I’m looking for how store variable on flash instead ram. In AVR-gcc is simply, but in XC 32 or 8 i can’t found this one

    October 10, 2017 at 8:13 pm
  • Ligo George

    You can declare the variable as a constant…… like const int a = 10;

    September 23, 2018 at 4:44 am
  • aymen lamri

    Please Can you help with a school project?
    Note I am using a program Micro-C

    November 24, 2018 at 3:07 am

Leave a Reply

Your email address will not be published. Required fields are marked *