Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 16

Unit III PIC Interrupts & Interfacing-I

Interrupt Vs Polling, IVT, Steps in executing interrupt, Sources of


interrupts;Enabling and disabling interrupts, Interrupt registers, Priority of
interrupts,Programming of: Timer using interrupts, External hardware interrupts,
Serial communication interrupt; Interfacing of LED, Interfacing 16X2 LCD (8 bits)
and Key board (4 x 4 Matrix), Interfacing Relay & Buzzer.

Interrupt Vs Polling:

In the context of PIC microcontrollers, both interrupts and polling are methods
used to handle external events:

Interrupts in PIC: PIC microcontrollers use interrupts to handle external events.


When an interrupt occurs, the processor stops its current task, saves its state, and
jumps to an interrupt service routine to handle the event. This allows the PIC to
respond quickly to time-sensitive events without constantly checking for them.

Polling in PIC: Polling in PIC involves the processor continuously checking a device
or condition to see if it needs attention. This method is simpler but less efficient
than interrupts because it wastes CPU cycles by constantly monitoring devices.

In a PIC microcontroller context, interrupts are often preferred for time-critical


tasks or when the processor needs to react quickly to external events. Polling, on
the other hand, may be used for simpler tasks where immediate response is not
critical. It's essential to choose the right method based on the specific
requirements of your project.

IVT:

The Interrupt Vector Table (IVT) in PIC microcontrollers is a table that holds the
addresses of interrupt service routines (ISRs) for various interrupt sources. When
an interrupt occurs, the processor looks up the corresponding address in the IVT
to jump to the appropriate ISR to handle the interrupt. This allows for efficient
interrupt handling in PIC microcontroller systems.

Steps in executing interrupt:

To execute an interrupt using a Programmable Interrupt Controller (PIC), you


typically follow these steps:

* Set up the PIC: Initialize the PIC by configuring its registers to recognize the
interrupt sources and assign them priorities.
* Configure interrupt sources: Enable the interrupt sources that you want to
trigger the interrupt.
* Enable interrupts: Enable interrupts globally by setting the appropriate bits
in the PIC and CPU registers.
* Define interrupt service routines: Write the Interrupt Service Routines
(ISRs) to handle the interrupt requests. These routines should execute the
necessary actions when the interrupt occurs.
* Trigger the interrupt: The interrupt source will generate the interrupt
request. When the interrupt occurs, the PIC will handle the interrupt by
invoking the corresponding ISR.
* Handle the interrupt: The ISR associated with the interrupt source will be
executed, performing the required tasks and then returning control to the
main program.

Sources of interrupts of PIC:

Some common sources of interrupts for a PIC (Peripheral Interface Controller)


microcontroller include external interrupts, timer interrupts, serial
communication interrupts (such as UART or SPI), and analog-to-digital converter
(ADC) interrupts. These interrupts help the microcontroller respond to events or
signals in a timely manner.
In PIC microcontrollers, interrupts can be categorized into various sources:

* External Interrupts: These interrupts are triggered by external events, such


as a change in voltage level on a specific pin, generating an interrupt
request.
* Timer Interrupts: PIC microcontrollers have built-in timers/counters that
can be configured to generate interrupts when a specific time period
elapses or when a certain count is reached.
* Serial Communication Interrupts: When using communication protocols like
UART (Universal Asynchronous Receiver-Transmitter) or SPI (Serial
Peripheral Interface), interrupts can be triggered to signal the arrival of new
data or the completion of a transmission/reception operation.
* Analog-to-Digital Converter (ADC) Interrupts: If ADC is performing
conversions continuously or upon specific triggers, interrupts can be used
to indicate when a conversion is complete and the digital output is ready to
be processed.
* Comparator Interrupts: PIC microcontrollers with analog comparators can
generate interrupts based on the comparison results (e.g., when the input
voltage crosses a predefined threshold).
* I2C Interrupts: In devices that use I2C (Inter-Integrated Circuit)
communication, interrupts can be triggered at various stages of the
communication process, such as when a byte is received or when a
communication error occurs.
* Watchdog Timer Reset Interrupts: A Watchdog Timer is used to reset the
microcontroller in case of a system malfunction. An interrupt can be
generated before a watchdog reset to allow the microcontroller to perform
corrective actions.

These are some common sources of interrupts in PIC microcontrollers. Each


interrupt source serves a specific purpose and helps in efficiently handling tasks
and responding to events in real-time.

Enabling and disabling interrupts:


In PIC microcontrollers, enabling and disabling interrupts involves setting and
clearing specific bits in the Interrupt Enable (INTCON) register and the Global
Interrupt Enable (GIE) bit in the Special Function Register (STATUS register).

The steps to enable and disable interrupts in PIC microcontrollers are as follows:

Enabling Interrupts:

Set the Global Interrupt Enable (GIE) bit in the STATUS register by executing the
following instruction: assembly BSF INTCON,GIE

Enable specific interrupt sources by setting their corresponding enable bits in the
INTCON register. For example, to enable external interrupts (INT0 and INT1), you
can set the INT0IE and INT1IE bits in the INTCON register.

Disabling Interrupts:

Clear the Global Interrupt Enable (GIE) bit in the STATUS register by executing the
following instruction: assembly BCF INTCON,GIE

Disable specific interrupt sources by clearing their corresponding enable bits in


the INTCON register. For example, to disable external interrupts (INT0 and INT1),
you can clear the INT0IE and INT1IE bits in the INTCON register.

Remember to handle interrupt service routines appropriately and to restore the


interrupt enable/disable state before exiting the ISR to avoid unexpected
behavior in your program.

Always refer to the specific PIC microcontroller's datasheet and programming


guide for detailed information on enabling and disabling interrupts, as the
procedure may vary slightly depending on the PIC model one is using.

Interrupt registers:

In a PIC microcontroller, interrupt-related registers are crucial for managing the


interrupt system. Here are some essential registers commonly used for handling
interrupts in PIC microcontrollers:
INTCON Register (Interrupt Control Register):

This register contains various bits related to interrupt control, such as enabling
specific interrupt sources, clearing interrupt flags, and controlling interrupt
priorities.

Some important bits in the INTCON register include:

GIE (Global Interrupt Enable): Enables or disables all interrupts globally.

INTE (External Interrupt Enable): Enables the external interrupt feature.

INTF (External Interrupt Flag): Indicates that an external interrupt occurred.

PIE1 and PIE2 Registers (Peripheral Interrupt Enable Registers):

These registers are used to enable or disable individual peripheral interrupts. Each
bit in these registers corresponds to a specific peripheral interrupt source.

PIR1 and PIR2 Registers (Peripheral Interrupt Request Registers):

These registers hold the status of pending interrupts for each peripheral. When
an interrupt occurs, the corresponding bit in these registers is set.

IPR1 and IPR2 Registers (Interrupt Priority Registers):

These registers are used to set the priority levels of different interrupts. Lower
priority interrupts can be made to wait until higher priority interrupts are
serviced.

RCON Register (Reset Control Register):

This register includes the IPEN bit, which enables or disables interrupt priority
levels. When IPEN is set, interrupt priority levels are active. The specific registers
and their functionalities may vary depending on the PIC microcontroller model.
It's crucial to refer to the datasheet and reference manual of the specific PIC
microcontroller you are working with for detailed information on interrupt
registers and their usage.
Priority of interrupts:

In PIC microcontrollers, interrupt priority levels can be set to manage the order in
which interrupts are serviced. The interrupt priority feature allows you to assign
different priority levels to interrupt sources, ensuring that higher priority
interrupts get serviced before lower priority interrupts. Here is a general overview
of interrupt priority levels in PIC microcontrollers:

High and Low Priority Interrupts:

PIC microcontrollers typically support two levels of interrupt priority: high priority
and low priority.

High priority interrupts are serviced before low priority interrupts.

Interrupt Priority Levels:

Some PIC microcontrollers offer multiple interrupt priority levels, allowing you to
assign different priorities to various interrupt sources.

The number of available priority levels can vary based on the specific PIC
microcontroller model.

Priority Control:

The IPEN bit (Interrupt Priority Enable) in the RCON register is used to enable
interrupt priority levels. When IPEN is set, interrupt priority levels are active.

Priority Assignment:

Interrupts can be assigned priority levels through programming. Higher priority


interrupts are assigned lower numeric values (e.g., 0 is the highest priority), while
lower priority interrupts are assigned higher numeric values.

Interrupt Service Routine (ISR):

When multiple interrupts occur simultaneously, the PIC microcontroller checks


the priority levels of the pending interrupts and services the highest priority
interrupt first.

Interrupts with the same priority level are serviced based on the order of
occurrence.

Interrupt Nesting:

Some PIC microcontrollers support interrupt nesting, allowing lower priority


interrupts to be interrupted by higher priority interrupts. Proper management of
nested interrupts is essential to avoid conflicts and ensure the correct functioning
of the system.

The specifics of interrupt priority implementation may vary between PIC


microcontroller families and individual models.

Programming of Timer using interrupts:

Programming a timer using interrupts in a PIC microcontroller involves setting up


the timer module, configuring the interrupt service routine (ISR), and enabling
interrupts. Here's a basic example of how you can program a timer using
interrupts on a PIC microcontroller (for illustration purposes, let's consider a
PIC16F877A):

Configure Timer Module:

Configure the timer module by setting the timer prescaler, timer mode, and timer
period according to your requirements. For example, setting up Timer1 in 16-bit
mode with a prescaler of 1:4: c T1CON = 0b00000001; // Timer1 module ON with
1:4 prescaler TMR1H = 0x0B; // Load the high byte of the initial timer value
TMR1L = 0xDB; // Load the low byte of the initial timer value

Configure Interrupts:

Enable Timer1 interrupt and global interrupt by setting appropriate bits: c


PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt INTCONbits.GIE = 1; // Enable
global interrupts

Interrupt Service Routine (ISR):

Write the Timer1 interrupt service routine to handle the timer overflow event.
For example: c void __interrupt() Timer1_ISR(void) { if(PIR1bits.TMR1IF) { // Your
code here // Clear the Timer1 interrupt flag PIR1bits.TMR1IF = 0; } }

Main Function:

In the main function,the timer can be started by setting the TMR1ON bit: c
T1CONbits.TMR1ON = 1; // Start Timer1

External ha:rdware interrupts:

External hardware interrupts in PIC microcontrollers can be used to trigger


specific actions in response to external events, such as a change in the state of an
external pin. Here's an example of how you can set up and use an external
hardware interrupt on a PIC microcontroller (considering PIC16F877A):

Configure External Interrupt:

Configure the specific pin for external interrupt. Each PIC microcontroller has
specific registers for external interrupts. c TRISBbits.TRISB0 = 1; // Set RB0 pin as
input INTCONbits.INTE = 1; // Enable external interrupt on RB0
OPTION_REGbits.INTEDG = 1; // Interrupt on rising edge

External Interrupt Service Routine (ISR):

Write the ISR to handle the external interrupt event. For example: c void
__interrupt() External_ISR(void) { if(INTCONbits.INTF) { // Your code here // Clear
the external interrupt flag INTCONbits.INTF = 0; } }

Main Function:

In the main function, enable global interrupts and start monitoring the external
interrupt. ```c INTCONbits.GIE = 1; // Enable global interrupts INTCONbits.INTE =
1; // Enable external interrupts

while(1) { // Main code here } ```

By setting up an external interrupt in your PIC microcontroller, responsive designs


can be created that react to external stimuli, making the system more versatile
and efficient.

Interfacing of LED:

Interfacing an LED with a PIC microcontroller, such as the PIC16F877A, is a


common beginner project. Here's a basic example of how you can interface an
LED with a PIC microcontroller using MPLAB X IDE and XC8 compiler:

Circuit Setup:

Connect an LED with a current-limiting resistor (e.g., 220 ohms) to one of the
GPIO pins of the PIC microcontroller (e.g., RB0).

Code Example:

Here is a simple code snippet to blink an LED connected to RB0 pin:

#include <xc.h>

// Configuration bits

#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/PGM pin has PGM function; low-voltage
programming enabled)

#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)

// Main code

void main() {

TRISB0 = 0; // Set RB0 as output

while(1) {

RB0 = 1; // Turn on the LED

__delay_ms(500); // Delay

Interfacing 16X2 LCD (8 bits):

Interfacing a 16x2 LCD with a PIC microcontroller using an 8-bit mode is a


common project. Here's a basic example of how you can interface a 16x2 LCD
with a PIC microcontroller such as PIC16F877A using MPLAB X IDE and XC8
compiler:
Circuit Setup:

Connect the 16x2 LCD with the PIC microcontroller as follows:

RS (Register Select) pin of the LCD to a GPIO pin of the PIC (e.g., RB0).

RW (Read/Write) pin of the LCD to GND.

EN (Enable) pin of the LCD to another GPIO pin of the PIC (e.g., RB1).

D0-D7 pins of the LCD to the GPIO pins of the PIC (e.g., RD0-RD7).

Code Example:

Library that be used is like the XC8 LCD library to simplify the interfacing process.
Below is a basic example using the library:

#include <xc.h>

#include <stdint.h>

#include "lcd.h" // Include the LCD library

void main() {

// Initialize the LCD

Lcd_Init();

// Display a message on the LCD

Lcd_Set_Cursor(1, 1); // Set the cursor to the first row, first column

Lcd_Write_String("Hello, LCD!");

while(1) {

// your code here


}

ou will need to download and include the LCD library in your project. You can find
various LCD libraries for PIC microcontrollers online.

Library Functions:

Typical functions in an LCD library include initializing the LCD, setting cursor
position, writing characters or strings to the LCD, etc.

Interfacing Key board (4 x 4 Matrix):

To interface a 4x4 matrix keyboard with a PIC microcontroller, you can follow
these steps:

* Connect the rows and columns of the keypad to the I/O pins of the PIC
microcontroller.
* Set the column pins as outputs and the row pins as inputs.
* Write a program to scan the keypad by sequentially driving each column
low and reading the corresponding row inputs to detect key presses.
* Identify the key pressed based on the row and column intersection in the
matrix.
* Perform the desired action based on the key pressed.
* Make sure to debounce the keys to handle any noise or multiple key
presses.

The code assumes that the column pins are connected to PORTB and the row pins
are connected to PORTD:

#include <xc.h>
// Define keymap for the keypad

char keys[4][4] = {

{'1', '2', '3', 'A'},

{'4', '5', '6', 'B'},

{'7', '8', '9', 'C'},

{'*', '0', '#', 'D'}

};

void keypad_init() {

TRISB = 0xF0; // Set columns as outputs and rows as inputs

TRISD = 0x0F;

LATB = 0xFF; // Set columns high

char keypad_scan() {

LATB = 0xFE; // Scan first column

__delay_ms(5); // Delay for stability

if (PORTDbits.RD0 == 0) return keys[0][0];

if (PORTDbits.RD1 == 0) return keys[1][0];

if (PORTDbits.RD2 == 0) return keys[2][0];

if (PORTDbits.RD3 == 0) return keys[3][0];


LATB = 0xFD; // Scan second column

__delay_ms(5);

if (PORTDbits.RD0 == 0) return keys[0][1];

if (PORTDbits.RD1 == 0) return keys[1][1];

if (PORTDbits.RD2 == 0) return keys[2][1];

if (PORTDbits.RD3 == 0) return keys[3][1];

LATB = 0xFB; // Scan third column

__delay_ms(5);

Interfacing Relay & Buzzer:

The example assumes that the relay is connected to pin RD0 and the buzzer is
connected to pin RD1:

#include <xc.h>

#define _XTAL_FREQ 20000000 // Crystal frequency, adjust as needed

void relay_buzzer_init() {

TRISD0 = 0; // Set RD0 as output for relay

TRISD1 = 0; // Set RD1 as output for buzzer

LATD0 = 0; // Initialize relay to off


LATD1 = 0; // Initialize buzzer to off

void relay_on() {

LATD0 = 1; // Turn on relay

void relay_off() {

LATD0 = 0; // Turn off relay

void buzzer_on() {

LATD1 = 1; // Turn on buzzer

void buzzer_off() {

LATD1 = 0; // Turn off buzzer

void main() {

relay_buzzer_init(); // Initialize pins for relay and buzzer


while(1) {

relay_on(); // Turn on relay

__delay_ms(1000); // Delay for 1 second

relay_off(); // Turn off relay

__delay_ms(1000); // Delay for 1 second

buzzer_on(); // Turn on buzzer

__delay_ms(500); // Delay for 0.5 second

buzzer_off(); // Turn off buzzer

__delay_ms(500); // Delay for 0.5 second

You might also like