0% found this document useful (0 votes)
43 views44 pages

ES Lec8

Uploaded by

Habiba Ghazi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views44 pages

ES Lec8

Uploaded by

Habiba Ghazi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

Tanta Higher Institute of Engineering

and Technology, THIET

‫االنظمة المدمجة‬
Embedded Systems
Course Code: ELE 413

Communication & Computer Engineering Department


Level: 400
Lec 8
PIC16F877A Microcontrollers
(Interrupts)
Interrupt
 Interrupt requests the microcontroller to stop the normal execution of
program and execute a special code (interrupt service routine = ISR).

 When interrupt occurs, the microcontroller does the following steps:


1) Stops the regular program execution and saves its current location

address (so that it can resume).

2) Jumps immediately to the ISR to execute it.

3) As soon as the ISR ends, the microcontroller restores its saved


location address and resumes program execution from where it left
off.
Main Program
Why Interrupt?
1. Servicing time critical applications:
 Real-time applications need immediate attention of the
CPU.
 For example, for safety reasons, it may be required to
shut down a plant whenever there is power failure or fire.
 In such applications, the CPU is required to stop
whatever it is doing and service the interrupting device.
2. Performing scheduled tasks:
 There are many applications that require the CPU to
perform scheduled tasks, such as updating the real-time
clock.
 These tasks are important and must be serviced at the
exact times.
Why Interrupt? cont’d
3. Preventing CPU from being tied up
 In some applications, the CPU is required to perform continuous
checks of I/O devices.
 While performing these checks, the CPU cannot perform other
duties.
 By moving the checking into interrupt routines, the checking can
be done in the background and the CPU is free to carry out other
tasks.
 For example, a multi- digit 7-segment display needs to be
refreshed continuously.
 If this task is done in the main program, then the CPU cannot do
other tasks.
 By moving the refreshing operation into the timer interrupt
routine, the CPU is free to do other tasks.
Common Sources of Interrupts

 PIC 16F877A has several interrupt sources, for example :

1. External interrupt

It provides a means for external hardware to generate


interrupts through the RB0/INT pin (interrupt pin).

2. TIMER interrupts

They have related interrupts (for example TMR0 Interrupt). In


most simple situation they can act like alarm clocks that can
interrupt the microcontroller at predefined intervals of time.
External
Interrupt
Pin
Configuration of External Interrupt and TMR0 Interrupt

 INTCON (Interrupt Configuration) register and OPTION_REG


are used to configure external Interrupt and TMR0 interrupt.

INTCON
Register TMR0IF

OPTION_REG
Register
1
INTCON
Register
INTCON
TMR0IF
Register

 GIE (Global Interrupt Enable):


 1 - Enables all interrupts.
 0 - Disables all interrupts.
 T0IE (TMR0 Overflow Interrupt Enable) controls interrupt enabled
by TMR0 overflow:
 1 - Enables TMR0 interrupt.
 0 - Disables TMR0 interrupt.
 INTE (RB0/INT External Interrupt Enable)
controls interrupt caused by changing the logic state of the RB0/INT pin
(External Interrupt).
 1 - Enables the RB0/INT external interrupt.
 0 - Disables the RB0/INT external interrupt.
INTCON
TMR0IF
Register

 TMR0IF (TMR0 Overflow Interrupt Flag bit)


Indicates TMR0 overflow, when counting reaches to 255 and starts to count
from 0 (255→0).

 1 - TMR0 register has overflowed (255→0). This bit must be


cleared in software.
 0 - TMR0 register has not overflowed.

 INTF (RB0/INT External Interrupt Flag bit):


Indicates the change of the RB0/INT pin logic state.

 1 - The RB0/INT external interrupt has occurred. This bit


must be cleared in software.
 0 - The RB0/INT external interrupt has not occurred.
2 OPTION_REG
Register
 PS0, PS1, PS2, PSA, T0SE, T0CS

 These bits control the configuration of TMR0/WD (as discussed


before in the pervious lecture).

 INTEDG (Interrupt Edge Select bit): INTCON.INTE = 1 is must

 0 - Interrupt on falling edge of the INT/RB0 pin (from high to low).


 1 – Interrupt on rising edge of the INT/RB0 pin (from low to high).
Interrupt Configuration

1 TMR0 Interrupt External Interrupt


2 (RB0/INT pin)

OPTION_REG = 0;
OPTION_REG = 0x07; OR
OR OPTION_REG.INTEDG = 0;
OPTION_REG = 0b00000111;

INTCON = 0xA0; INTCON = 0x90;


OR OR
INTCON = 0b10100000; (0xA0) INTCON = 0x10010000; (0x90)
OR OR
INTCON.GIE = 1; INTCON.GIE = 1;
INTCON.T0IE = 1; INTCON.INTE = 1;
EX1: Without any Interrupt

 Write a microcontroller PIC16F877A C program to toggle all bits


of PORTD every 10 sec, while at the same time the
microcontroller is doing AND, OR, XOR between pin5, pin6, and
pin7 of PORTB continuously as follows:
portB.f1 = portB.f5 & portB.f6 & portB.f7
portB.f2 = portB.f5 | portB.f6 | portB.f7
portB.f3 = portB.f5 ^ portB.f6 ^ portB.f7
 PORTD is initialized by 55H
void main( ) {

trisB = 0b11100000;
trisD = 0;
portD = 0x55;

for( ; ; ) {
portD = ~portD;
delay_ms(10000); // any time-consuming block

portB.f1 = portB.f5 & portB.f6 & portB.f7;


portB.f2 = portB.f5 | portB.f6 | portB.f7;
portB.f3 = portB.f5 ^ portB.f6 ^ portB.f7;

}
}
EX2: TMR0 Interrupt

 Write a microcontroller PIC16F877A C program to use TMR0


interrupt to toggle all bits of PORTD every 10 sec, while at the
same time the microcontroller is doing AND, OR, XOR between
pin5, pin6, and pin7 of PORTB continuously as follows:
portB.f1 = portB.f5 & portB.f6 & portB.f7
portB.f2 = portB.f5 | portB.f6 | portB.f7
portB.f3 = portB.f5 ^ portB.f6 ^ portB.f7
 PORTD is initialized by 55H

 Assume (1:256) Prescaler is assigned to TMR0 and f = 4 MHz.


 OPTION_REG Configuration:

0 0 0 0 0 1 1 1

OPTION_REG = 0x07;
 Calculate the required no. of overflows to get time equal to 10 sec
• Assume The initial value of TMR0 = 0 (T0 =0)

• Overflow Time of TMR0 = (256-0) x prescale x 4 x clock_period


-6
= 256 x 256 x 4 x 0.25*10 sec = 65536 μSec
1 overflow 65536 μSec

X overflows 10 Sec

10
X = = 152.59 = 153
65536 * 10-6

The required no. of overflows to get time equal to 10 sec = 153 overflows.
int overflows_no = 0;
void interrupt( ) {
if(INTCON.TMR0IF == 1) {
overflows_no++; // Interrupt causes overflows_no to be incremented by 1
INTCON.TMR0IF = 0; //Clear the interrupt flag or INTCON.B2 = 0; or INTCON.F2 = 0
TMR0 = 0; //TMR0 returns to its initial value (T0)
}
if (overflows_no = = 153) { // 10 sec delay
PORTD = ~PORTD; // Toggle PORTD
overflows_no = 0;
}
}
void main( ) {
TRISB = 0b11100000; // pin7, pin6, and pin5 are input
TRISD = 0; // PORTD O/P
PORTD = 0x55;
OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0
INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts
TMR0 = 0; // Timer TMR0 counts from 0 to 255
while(1){
portB.f1 = portB.f5 & portB.f6 & portB.f7;
portB.f2 = portB.f5 | portB.f6 | portB.f7;
portB.f3 = portB.f5 ^ portB.f6 ^ portB.f7;
}
}
EX3: RB0/INT Interrupt

 Write a microcontroller PIC16F877A C program to use


external interrupt (RB0/INT pin) to toggle all bits of PORTD,
while at the same time the microcontroller is doing AND,
OR, XOR between pin5, pin6, and pin7 of PORTB
continuously as follows:
portB.f1 = portB.f5 & portB.f6 & portB.f7
portB.f2 = portB.f5 | portB.f6 | portB.f7
portB.f3 = portB.f5 ^ portB.f6 ^ portB.f7
 PORTD is initialized by 55H
void interrupt( ) {
If ( INTCON.INTF = = 1 ) {
INTCON.INTF = 0; //Clear the interrupt flag or INTCON.B1 = 0;
PORTD = ~PORTD; // Toggle PORTD
}
}

void main( ) {
TRISB = 0b11100001;
TRISD = 0; // PORTD is O/P
PORTD = 0x55;
OPTION_REG = 0; // Interrupt on falling edge of the RB0/INT pin
INTCON = 0x90; // Enable RB0/INT pin interrupt and Global Interrupts
while(1) {
portB.f1 = portB.f5 & portB.f6 & portB.f7;
portB.f2 = portB.f5 | portB.f6 | portB.f7;
portB.f3 = portB.f5 ^ portB.f6 ^ portB.f7;
}
}
PIC16F877A Microcontrollers
(Liquid Crystal Display (LCD))
Additional Notes:
•FUNCTION_SET (0x38):
• This command sets the LCD in 8-bit mode.
• If you want 4-bit mode, you would use 0x28 instead.
•DISPLAY_ON (0x0C):
• Turns the display ON, but the cursor is hidden and does not blink.
• If you want the cursor to be visible or blinking, you would send different
commands:
• 0x0E → Display ON + Cursor ON.
• 0x0F → Display ON + Cursor ON + Blinking.
•ENTRY_MODE_SET (0x06):
• After writing a character, the cursor automatically moves one position to the
right.
Typical Initialization Sequence:
When you power up the LCD, you usually send the commands in this order:
LCD_WriteCommand(FUNCTION_SET); // Function set (8-bit, 2 lines, 5x8 font)
LCD_WriteCommand(DISPLAY_ON); // Display ON, cursor OFF
LCD_WriteCommand(CLEAR_LCD); // Clear screen
LCD_WriteCommand(ENTRY_MODE_SET); // Set entry mode (move cursor right
after each character)
Definition Hex Value Function

Clears the entire LCD screen and moves the cursor


#define CLEAR_LCD 0x01 0x01
to the first row, first column (home position).

Returns the cursor to the home position without


#define RETURN_HOME 0x02 0x02
clearing the display.

Sets the entry mode: after each character is written,


#define ENTRY_MODE_SET 0x06 0x06
the cursor automatically moves to the right.

Turns the display ON without showing the cursor


#define DISPLAY_ON 0x0C 0x0C
or blinking.

Sets LCD mode: 8-bit interface, 2-line display, and


#define FUNCTION_SET 0x38 0x38
5x8 dot font.
// LCD data pins (if using 8-bit mode)
#define LCD_DATA PORTB
// LCD commands
#define CLEAR_LCD 0x01
#define RETURN_HOME 0x02
#define ENTRY_MODE_SET 0x06
#define DISPLAY_ON 0x0C
#define FUNCTION_SET 0x38

void LCD_Init(void);
void LCD_WriteCommand(unsigned char cmd);
void LCD_WriteData(unsigned char data);
void LCD_GoTo(unsigned char row, unsigned char col);
void LCD_WriteString(char *str);
void main(void) {
// Initialize the LCD
TRISB = 0x00; // Set PORTB as output (for data)
TRISC = 0x00; // Set PORTC as output (for control pins)
LCD_Init(); // Initialize the LCD
// Set the cursor to the beginning of the first line (Row 1, Column 1)
LCD_GoTo(1, 1);
LCD_WriteString("Power");
// Set the cursor to the beginning of the second line (Row 2, Column 1)
LCD_GoTo(2, 1);
LCD_WriteString("Engineering");
while (1) {
// Main loop (Nothing to do here since the text is displayed)
}
}
void LCD_Init(void) {
__delay_ms(15); // Wait for LCD to power up
LCD_WriteCommand(FUNCTION_SET); // Function set (8-bit, 2 lines, 5x8 font)
LCD_WriteCommand(DISPLAY_ON); // Display ON, cursor OFF
LCD_WriteCommand(CLEAR_LCD); // Clear screen
LCD_WriteCommand(ENTRY_MODE_SET); // Set entry mode (move cursor right
after each character)
}
void LCD_WriteCommand(unsigned char cmd) {
RS = 0; // Select command register
RW = 0; // Write mode
LCD_DATA = cmd; // Send the command
E = 1; // Enable pulse
__delay_ms(1); // Short delay
E = 0; // Disable pulse
__delay_ms(2); // Command execution time
}
void LCD_WriteData(unsigned char data) {
RS = 1; // Select data register
RW = 0; // Write mode
LCD_DATA = data; // Send the data
E = 1; // Enable pulse
__delay_ms(1); // Short delay
E = 0; // Disable pulse
__delay_ms(1); // Data write delay
}
void LCD_GoTo(unsigned char row, unsigned char col) {
unsigned char address;

if (row == 1) {
address = 0x00 + col - 1; // Row 1
} else if (row == 2) {
address = 0x40 + col - 1; // Row 2
}

LCD_WriteCommand(0x80 | address); // Set cursor position


}
void LCD_WriteString(char *str) {
while (*str) {
LCD_WriteData(*str++);
}
}

You might also like