PIC18 Microcontroller: What It Is and How to Use it

Posted by

Introduction to PIC18 Microcontroller

The PIC18 microcontroller is a powerful and versatile microcontroller developed by Microchip Technology. It is widely used in various applications, from consumer electronics to industrial automation. The PIC18 family offers a range of features and capabilities that make it an attractive choice for embedded systems designers.

What is a Microcontroller?

A microcontroller is a small computer on a single integrated circuit, containing a processor, memory, and programmable input/output peripherals. Microcontrollers are designed for embedded applications, where they are used to control various devices and processes.

Why Choose PIC18 Microcontroller?

The PIC18 microcontroller offers several advantages over other microcontrollers:

  1. High Performance: PIC18 microcontrollers feature a powerful 8-bit processor with a pipeline architecture, allowing for fast execution of instructions.
  2. Large Memory: PIC18 microcontrollers offer up to 128KB of flash memory and 4KB of RAM, providing ample space for program storage and data manipulation.
  3. Extensive Peripheral Set: PIC18 microcontrollers come with a wide range of built-in peripherals, including timers, PWM modules, UART, SPI, I2C, and analog-to-digital converters (ADC).
  4. Low Power Consumption: PIC18 microcontrollers are designed for low power consumption, making them suitable for battery-powered applications.
  5. Easy to Use: PIC18 microcontrollers are supported by a wide range of development tools and libraries, making it easy for developers to create applications.

PIC18 Microcontroller Architecture

CPU and Memory

The PIC18 microcontroller features an 8-bit CPU with a pipeline architecture, allowing for faster execution of instructions compared to non-pipelined architectures. The CPU operates at frequencies up to 64 MHz, depending on the specific device.

PIC18 microcontrollers offer up to 128KB of flash memory for program storage and up to 4KB of RAM for data storage. The flash memory can be programmed and erased up to 100,000 times, making it suitable for applications that require frequent firmware updates.

Peripherals

PIC18 microcontrollers come with a wide range of built-in peripherals, including:

  1. Timers: PIC18 microcontrollers feature multiple 8-bit and 16-bit timers, which can be used for timing-related tasks such as generating PWM signals or measuring time intervals.
  2. PWM Modules: PIC18 microcontrollers offer multiple PWM modules, which can be used to generate analog signals for controlling motors, lights, or other devices.
  3. UART: PIC18 microcontrollers feature one or more UART modules, which can be used for serial communication with other devices.
  4. SPI: PIC18 microcontrollers offer one or more SPI modules, which can be used for high-speed synchronous serial communication with other devices.
  5. I2C: PIC18 microcontrollers feature one or more I2C modules, which can be used for communication with other devices using the I2C protocol.
  6. ADC: PIC18 microcontrollers offer multiple analog-to-digital converter (ADC) modules, which can be used to measure analog signals such as temperature, pressure, or light intensity.

Interrupt System

PIC18 microcontrollers feature a powerful interrupt system, which allows the CPU to respond to external events or internal conditions. The interrupt system supports multiple interrupt sources, including timers, UART, SPI, I2C, and external interrupt pins.

Getting Started with PIC18 Microcontroller

Development Tools

To get started with PIC18 microcontroller development, you will need the following tools:

  1. MPLAB X IDE: MPLAB X is the integrated development environment (IDE) provided by Microchip for developing applications for PIC microcontrollers. It includes a code editor, debugger, and project management tools.
  2. XC8 Compiler: XC8 is the C compiler provided by Microchip for PIC18 microcontrollers. It supports the ANSI C programming language and includes a range of optimization features.
  3. PICkit Programmer: The PICkit programmer is a low-cost programmer and debugger for PIC microcontrollers. It can be used to program and debug PIC18 microcontrollers.
  4. Development Board: A development board is a pre-built circuit board that includes a PIC18 microcontroller and various peripherals such as LEDs, buttons, and connectors. Development boards make it easy to get started with PIC18 microcontroller development without having to design and build your own hardware.

Hello World Example

Here’s a simple “Hello World” example that demonstrates how to use the UART module on a PIC18 microcontroller to send a message to a terminal program:

#include <xc.h>

#define _XTAL_FREQ 8000000 // 8 MHz crystal oscillator

void main() {
    // Configure UART module
    TRISCbits.TRISC6 = 0; // Set TX pin as output
    TXSTAbits.SYNC = 0; // Asynchronous mode
    TXSTAbits.BRGH = 1; // High-speed baud rate
    BAUDCONbits.BRG16 = 0; // 8-bit baud rate generator
    SPBRG = 51; // 9600 baud rate at 8 MHz
    TXSTAbits.TXEN = 1; // Enable transmitter

    // Send "Hello, World!" message
    while (1) {
        while (!TXSTAbits.TRMT); // Wait for previous transmission to complete
        TXREG = 'H';
        while (!TXSTAbits.TRMT);
        TXREG = 'e';
        while (!TXSTAbits.TRMT);
        TXREG = 'l';
        while (!TXSTAbits.TRMT);
        TXREG = 'l';
        while (!TXSTAbits.TRMT);
        TXREG = 'o';
        while (!TXSTAbits.TRMT);
        TXREG = ',';
        while (!TXSTAbits.TRMT);
        TXREG = ' ';
        while (!TXSTAbits.TRMT);
        TXREG = 'W';
        while (!TXSTAbits.TRMT);
        TXREG = 'o';
        while (!TXSTAbits.TRMT);
        TXREG = 'r';
        while (!TXSTAbits.TRMT);
        TXREG = 'l';
        while (!TXSTAbits.TRMT);
        TXREG = 'd';
        while (!TXSTAbits.TRMT);
        TXREG = '!';
        while (!TXSTAbits.TRMT);
        TXREG = '\r';
        while (!TXSTAbits.TRMT);
        TXREG = '\n';
    }
}

This example configures the UART module to transmit at 9600 baud and sends the message “Hello, World!” to a terminal program. The while (!TXSTAbits.TRMT) statements ensure that each character is transmitted before sending the next one.

Advanced Topics

Interrupts

Interrupts are a powerful feature of PIC18 microcontrollers that allow the CPU to respond to external events or internal conditions. When an interrupt occurs, the CPU suspends its current operation, saves its state, and jumps to a special function called an interrupt service routine (ISR).

To use interrupts in a PIC18 microcontroller, you need to follow these steps:

  1. Enable the interrupt source: Each interrupt source has a corresponding enable bit in a control register. You need to set this bit to enable the interrupt.
  2. Set the interrupt priority: PIC18 microcontrollers support two levels of interrupt priority: high and low. You can set the priority of each interrupt source using the IPR registers.
  3. Write the ISR: The ISR is a special function that is called when the interrupt occurs. You need to write the code that handles the interrupt in this function.
  4. Enable global interrupts: To enable interrupts globally, you need to set the GIE bit in the INTCON register.

Here’s an example that demonstrates how to use interrupts to toggle an LED every second using Timer0:

#include <xc.h>

#define _XTAL_FREQ 8000000 // 8 MHz crystal oscillator

// Configure Timer0 interrupt
void __interrupt() isr() {
    if (INTCONbits.TMR0IF) {
        INTCONbits.TMR0IF = 0; // Clear interrupt flag
        TMR0 = 0; // Reset Timer0
        LATCbits.LATC0 = ~LATCbits.LATC0; // Toggle LED
    }
}

void main() {
    // Configure Timer0
    T0CONbits.T0CS = 0; // Internal instruction cycle clock
    T0CONbits.PSA = 0; // Prescaler assigned to Timer0
    T0CONbits.T0PS = 0b111; // 1:256 prescaler
    TMR0 = 0; // Reset Timer0
    T0CONbits.TMR0ON = 1; // Enable Timer0

    // Configure LED pin
    TRISCbits.TRISC0 = 0; // Set RC0 as output
    LATCbits.LATC0 = 0; // Turn off LED

    // Enable Timer0 interrupt
    INTCONbits.TMR0IE = 1; // Enable Timer0 interrupt
    INTCONbits.TMR0IF = 0; // Clear interrupt flag
    INTCONbits.GIE = 1; // Enable global interrupts

    while (1); // Wait for interrupts
}

In this example, Timer0 is configured to generate an interrupt every second using a 1:256 prescaler. The isr() function is the ISR that handles the Timer0 interrupt by toggling the LED connected to pin RC0. The main() function configures the Timer0 and LED pin, enables the Timer0 interrupt, and waits for interrupts to occur.

PWM

Pulse-width modulation (PWM) is a technique used to generate analog signals using digital means. PWM works by rapidly turning a digital output on and off, with the ratio of on-time to off-time determining the average voltage of the signal.

PIC18 microcontrollers include dedicated PWM modules that make it easy to generate PWM signals. To use the PWM module, you need to follow these steps:

  1. Configure the PWM period: The PWM period determines the frequency of the PWM signal. You can set the period using the PR2 register and the Timer2 prescaler.
  2. Configure the PWM duty cycle: The PWM duty cycle determines the ratio of on-time to off-time. You can set the duty cycle using the CCPR1L and CCP1CON registers.
  3. Configure the PWM pin: You need to configure the pin that will output the PWM signal as an output.
  4. Enable the PWM module: To enable the PWM module, you need to set the CCP1M bits in the CCP1CON register to 0b1100.

Here’s an example that demonstrates how to generate a 50% duty cycle PWM signal on pin RC2 with a frequency of 1 kHz:

#include <xc.h>

#define _XTAL_FREQ 8000000 // 8 MHz crystal oscillator

void main() {
    // Configure PWM
    TRISCbits.TRISC2 = 0; // Set RC2 as output
    PR2 = 249; // Set PWM period to 1 kHz
    CCPR1L = 125; // Set PWM duty cycle to 50%
    CCP1CONbits.DC1B = 0b00; // Set PWM duty cycle to 50%
    CCP1CONbits.CCP1M = 0b1100; // Enable PWM mode
    T2CONbits.T2CKPS = 0b01; // Set Timer2 prescaler to 1:4
    T2CONbits.TMR2ON = 1; // Enable Timer2

    while (1); // Wait forever
}

In this example, the PWM period is set to 1 kHz by setting the PR2 register to 249 and the Timer2 prescaler to 1:4. The PWM duty cycle is set to 50% by setting the CCPR1L register to 125 and the DC1B bits in the CCP1CON register to 0b00. Finally, the PWM module is enabled by setting the CCP1M bits in the CCP1CON register to 0b1100.

ADC

The analog-to-digital converter (ADC) is a module that converts an analog voltage to a digital value. PIC18 microcontrollers include one or more ADC modules that can be used to measure analog signals such as temperature, pressure, or light intensity.

To use the ADC module, you need to follow these steps:

  1. Configure the ADC clock: The ADC requires a clock signal to operate. You can select the clock source and prescaler using the ADCON0 and ADCON2 registers.
  2. Configure the ADC input: You need to select the analog input channel that you want to measure using the ADCON0 register.
  3. Configure the ADC result format: You can select the format of the ADC result (left-justified or right-justified) using the ADCON2 register.
  4. Start the ADC conversion: To start an ADC conversion, you need to set the GO/DONE bit in the ADCON0 register.
  5. Wait for the conversion to complete: You need to wait for the ADC conversion to complete before reading the result. You can check the GO/DONE bit to see if the conversion is still in progress.
  6. Read the ADC result: Once the conversion is complete, you can read the result from the ADRESH and ADRESL registers.

Here’s an example that demonstrates how to use the ADC to measure the voltage on analog input AN0:

#include <xc.h>

#define _XTAL_FREQ 8000000 // 8 MHz crystal oscillator

void main() {
    // Configure ADC
    ADCON0bits.ADCS = 0b01; // Fosc/8
    ADCON1bits.VCFG0 = 0; // Vref+ = Vdd
    ADCON1bits.VCFG1 = 0; // Vref- = Vss
    ADCON1bits.PCFG = 0b1110; // AN0 is analog input
    ADCON2bits.ADCS = 0b110; // Fosc/64
    ADCON2bits.ACQT = 0b010; // 4 Tad acquisition time
    ADCON2bits.ADFM = 1; // Right-justified result
    ADCON0bits.ADON = 1; // Enable ADC

    while (1) {
        ADCON0bits.CHS = 0b0000; // Select AN0
        ADCON0bits.GO_DONE = 1; // Start conversion
        while (ADCON0bits.GO_DONE); // Wait for conversion to complete
        int result = (ADRESH << 8) | ADRESL; // Read result
    }
}

In this example, the ADC is configured to use a clock of Fosc/64, with a Vref+ of Vdd and a Vref- of Vss. AN0 is selected as the analog input, and the result is right-justified. The ADC is enabled, and a conversion is started on AN0. The program waits for the conversion to complete and then reads the result from the ADRESH and ADRESL registers.

FAQs

  1. What is the difference between PIC18 and other PIC microcontrollers?
  2. PIC18 microcontrollers are more powerful and feature-rich than other PIC microcontrollers such as PIC12 and PIC16. PIC18 microcontrollers have larger memory, more peripherals, and faster clock speeds.

  3. Can PIC18 microcontrollers be programme

Leave a Reply

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