Learn To Write Code For 8051, Arduino, AVR, dsPIC, PIC, STM32 ARM Microcontroller, etc.
Coding Embedded Controller With C/C++.
Printed Circuit Board (PCB) Project For Electronics Hobbyists.
External interrupt is an outside event that notify the controller. Controller may response or ignore to this event by its routine. Using this feature main program loop doesn’t need to poll for this event, reducing latency in program.
Pin diagram – RB0 can trigger external interrupt to controller.
This interrupt caused by input logic change on RB0 of Port B. It’s programmable by user. Logic change could be,
Rising edge (from low to high logic)
Falling edge (from high to low logic)
With the advantage of internal weak pull-up resistor of Port B, it’s suitable to select interrupt on falling edge when using with push button input.
External Interrupt Programming
Interrupt programming in C is simple. Programmer doesn’t need to save context before program jumping to Interrupt Service Routine (ISR), and restoring context after ISR executing is completed.
Programmer just needed to select and prepare targeted interrupt source. In ISR it’s required to write any C code to handle interrupt source.
void interrupt extISR(void){
if(INTE&&INTF){
toggleLed^=1;
INTF=0;
}
}
Schematic Design
We configure RB0 as digital input with internal weak pull-up resistor enabled. It trigger interrupt signal whenever connected input button is pressed, changing input logic from high to low. Each time interrupt occurs, an LED connects to RB7 toggles. Crystal oscillator is 20MHz supplied by a +5V DC voltage source.
Schematic Diagram
Programming in C
Main program loop in C blinks output LED connects to RB4. External interrupt is handled in ISR.
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#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)
Inprevious sectionwe getting started with PIC16F877A with LED toggling on Port C. Now let move to its digital I/O port programming using XC8.
PIC16F877A has up to five digital I/O ports,
Port A
Port B
Port C
Port D
and Port E
These ports are bi-directional I/O by program setting.
PIC16F877A pin diagram
Port C and Port D
These two ports are discussed first due to their pure digital I/O functions.
Port C
Port C locates at 07h in Special Function Register (SFR). Its data direction is controlled by TRISC register, locates at 87h in SFR.
Registers associate with Port C
Setting TRISC conveys Port C to input direction, accepting digital input data from outside world. Clearing TRISC to make Port C outputs its data via its output pins.
Port D
Port D locates at 08h in SFR. Its data direction is controlled by TRISD register, locates at 88h in SFR.
Setting TRISD conveys Port D to input direction, accepting digital data from outside world. Clearing this register to make Port D to outputs its data from its output pins.
Registers associate with Port D
Port D has another digital function – 8-bit wide microprocessor microprocessor port (Parallel Slave Port).
Programming Example
A simple example shows how to read digital input Port C. Its digital data outputs on Port D.
Schematic Diagram
Digital input made by a DIP switch with a resistor network. Digital output is an LED bar-graph.
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#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)
void main(void){
/*Clear IO*/
PORTC=0x00;
PORTD=0x00;
/*Port C input*/
TRISC=0xFF;
/*Port D output*/
TRISD=0x00;
while(1){
PORTD=PORTC;
for(int i=0;i<25;i++);
}
}
Click hereto download zip file of this programming example.
Port B
Port B is an 8-bit wide bi-directional I/O. Its data direction is controlled by TRISD register. PORTB is its I/O register locate at 07h in SFR. TRISB locates at 87h.
Details
Setting TRISB allows Port B to accept digital input data, as it works in input data direction. By clearing it, digital data flows out via PORTB I/O register to output devices.
Register associate with Port B
RB0 of Port B can trigger an external interrupt but we don’t discuss it here. Port B has an internal weak pull up resistors. This feature is enabled by clearing RBPU bit of Option Register (OPTION_REG).
Programming Example
We will show how to configure Port B as digital input with its internal weak pull up resistors. Here Port D is a digital output port connecting to bar-graph LED.
Port B doesn’t need external resistors as it’s internally connected to VDD via its weak pull up resistors.
/*
* PIC16F877A Port B digital I/O Programming in XC8
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#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)
Port A is an 8-bit wide bi-directional I/O. Its data direction is controlled by TRISA register.
Details
PORTA is its I/O buffer locates at 05h in SFR. Its data direction control TRISA locates at 85h in SFR. Setting TRISA make this port as digital input, otherwise it becomes digital output.
Registers associate with Port A
Port A is multiplexed with Analog to Digital Converter (ADC) input. Setting Analog to Digital Control Register 1 (ADCON1) to 0x06 to analog input function, allowing this port work solely in digital I/O.
Programming Example
We make a simple port reading from Port A. Its digital value will be displayed on Port B.
Port A is usable only five bits. So I mask other two remaining MSB.
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#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)