How to Control the GPIO of PIC16F877A using MPLAB X IDE

Posted

in

by

The PIC16F877A microcontroller is a popular choice for embedded systems development due to its versatility and ease of use. One of the essential aspects of working with microcontrollers is controlling General Purpose Input/Output (GPIO) pins. In this blog post, we will explore how to control the GPIO pins of the PIC16F877A using MPLAB X IDE, a powerful Integrated Development Environment.

Prerequisites:
To follow along with this tutorial, you will need the following:

  1. PIC16F877A microcontroller.
  2. MPLAB X IDE installed on your computer.
  3. MPLAB XC8 Compiler.

Step 1: Create a New Project
Launch MPLAB X IDE and create a new project by navigating to File -> New Project. Select “Microchip Embedded” under “Categories” and “Standalone Project” under “Projects”. Choose the PIC16F877A as the device and specify a name and location for your project. Click “Finish” to create the project.

Step 2: Configure the GPIO Pins
To control the GPIO pins, we need to configure them as inputs or outputs. In the project window, open the “main.c” source file. Locate the main function and add the necessary code to configure the GPIO pins.

To set a pin as an output, use the TRISx register, where x represents the port name (A, B, C, etc.). For example, to set RB0 as an output pin, use the following code:

TRISBbits.TRISB0 = 0; // Set RB0 as an output pin

To set a pin as an input, use the same TRISx register and set the corresponding bit to 1. For example, to set RA2 as an input pin, use the following code:

TRISAbits.TRISA2 = 1; // Set RA2 as an input pin

Step 3: Control the GPIO Pins Once the GPIO pins are configured, we can control their state by manipulating the corresponding PORT registers. To set an output pin high (logic level 1), write 1 to the corresponding bit in the PORT register. For example, to set RB0 high, use the following code:

PORTBbits.RB0 = 1; // Set RB0 high

To set an output pin low (logic level 0), write 0 to the corresponding bit in the PORT register. For example, to set RB0 low, use the following code:

PORTBbits.RB0 = 0; // Set RB0 low

To read the state of an input pin, you can directly access the corresponding PORT register. For example, to read the state of RD2, use the following code:

if (PORTAbits.RD2 == 1) {
    // RD2 is high
} else {
    // RD2 is low
}

PORTA: It is configured as an analog port by default.
When you want to use it as a Digital I/O port, you have to configure the ADCON1 register.

Demo Code

/* 
 * File:   main.c
 * Author: abhay
 *
 * Created on July 14, 2023, 12:05 AM
 */

// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#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)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define _XTAL_FREQ 16000000
#include <xc.h>
#include <pic16f877a.h>
#include <stdio.h>
#include <stdlib.h>
#include "board.h"

/*
 * 
 */
int main(int argc, char** argv) {
    /*
     * TRIS = Data Direction Register
     * 0 = OUTPUT
     * 1 = INPUT

     */
// Make the Pin 1 of PORT D as output 
      TRISD &= ~(1 << 1); // LED RD1 as OUTPUT
      TRISD1 = 0; // RD1 as OUTPUT
     
    
    // Make the Pin 0 of PORT A as digital input
    ADCON1bits.PCFG0 = 0;
    ADCON1bits.PCFG1 = 1;
    ADCON1bits.PCFG2 = 1;
    ADCON1bits.PCFG3 = 0;
    TRISA0 = 1; // button 
    
    while (1) {
        if((RA0 ) == 1)
        {
            RD1 = 1;
        }
        else {
            PORTD &= ~(1<<1);
        }
       
    }

    return (EXIT_SUCCESS);
}

Step 4: Build and Program the Microcontroller
Now that we have written the code, it’s time to build and program the microcontroller. Connect your PIC16F877A microcontroller to your computer via a suitable programmer/debugger. Ensure that the proper hardware connections are made.

Step 5: Test the GPIO Control
Once the programming is complete, disconnect the programming cable and power the microcontroller using an appropriate power supply. Connect LEDs, switches, or other devices to the configured GPIO pins. Execute the code on the microcontroller and observe the desired behavior of the GPIO pins based on the control logic implemented in your code.

Conclusion:
Controlling the GPIO pins of the PIC16F877A microcontroller using MPLAB X IDE is a fundamental skill in embedded systems development. By following this step-by-step guide, you have learned how to configure the GPIO pins as inputs or outputs and manipulate their states using the appropriate registers. With this knowledge, you can now start building a wide range of projects that involve interacting with the external world through GPIO pins.

Remember to refer to the PIC16F877A datasheet for detailed information on register names, bit assignments, and other specific details related to the microcontroller.

Happy coding and exploring the world of embedded systems!

Comments

Leave a Reply

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