Tuesday, November 9, 2021

PIC16F877A External Interrupt Programming in XC8

 

Introduction

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.

PIC16F877A External Interrupt Programming in XC8


PIC16F877A External Interrupt Programming in XC8
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.

  1. void interrupt extISR(void){
  2. if(INTE&&INTF){
  3. toggleLed^=1;
  4. INTF=0;
  5. }
  6. }

 

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.

PIC16F877A External Interrupt Programming in XC8
Schematic Diagram

 

Programming in C

Main program loop in C blinks output LED connects to RB4. External interrupt is handled in ISR.

  1. /*
  2.  * PIC16F877A External Interrupt Programming
  3.  * in MPLABX XC8 Example
  4.  */
  5. #include <xc.h>
  6.  
  7. // PIC16F877A Configuration Bit Settings
  8. // CONFIG
  9. #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
  10. #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
  11. #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
  12. #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
  13. #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)
  14. #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
  15. #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
  16. #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
  17.  
  18. #define _XTAL_FREQ 20000000
  19. #define blinkLed RB4
  20. #define toggleLed RB7
  21.  
  22. void main(void){
  23. /*Clear Port B*/
  24. PORTB=0x00;
  25. /*RB0 input*/
  26. TRISB=0x01;
  27. /*Turn on pull up resistor*/
  28. nRBPU=0;
  29. /*Enable external interrupt*/
  30. INTE=1;
  31. /*External interrupt on falling edge*/
  32. INTEDG=0;
  33. /*Turn on global interrupt*/
  34. GIE=1;
  35. /*Clear external interrupt flag*/
  36. INTF=0;
  37. /*Loop of main program*/
  38. while(1){
  39. blinkLed^=1;
  40. __delay_ms(500);
  41. }
  42. }
  43.  
  44. /*Interrupt Service Routine*/
  45. void interrupt extISR(void){
  46. /*Check interrupt flag*/
  47. if(INTE&&INTF){
  48. toggleLed^=1;
  49. INTF=0;
  50. }
  51. }

Click here to download source file.  



Saturday, November 6, 2021

PIC16F877A Basic Digital I/O Port Programming

Introduction

In previous section we 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

PIC16F877A Basic Digital I/O Port Programming

These ports are bi-directional I/O by program setting.

PIC16F877A Basic Digital I/O Port Programming
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.

PIC16F877A Basic Digital I/O Port Programming
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.

PIC16F877A Basic Digital I/O Port Programming
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.

PIC16F877A Basic Digital I/O Port Programming
Schematic Diagram

Digital input made by a DIP switch with a resistor network. Digital output is an LED bar-graph.

  1. /*
  2.  * PIC16F877A digital I/O Programming in XC8
  3.  */
  4. #include <xc.h>
  5.  
  6. // PIC16F877A Configuration Bit Settings
  7. // CONFIG
  8. #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
  9. #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
  10. #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
  11. #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
  12. #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)
  13. #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
  14. #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
  15. #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
  16.  
  17. void main(void){
  18. /*Clear IO*/
  19. PORTC=0x00;
  20. PORTD=0x00;
  21. /*Port C input*/
  22. TRISC=0xFF;
  23. /*Port D output*/
  24. TRISD=0x00;
  25. while(1){
  26. PORTD=PORTC;
  27. for(int i=0;i<25;i++);
  28. }
  29. }

 Click here to 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.

PIC16F877A Basic Digital I/O Port Programming
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.

  1. /*
  2.  * PIC16F877A Port B digital I/O Programming in XC8
  3.  */
  4. #include <xc.h>
  5.  
  6. // PIC16F877A Configuration Bit Settings
  7. // CONFIG
  8. #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
  9. #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
  10. #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
  11. #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
  12. #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)
  13. #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
  14. #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
  15. #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
  16.  
  17. void main(void){
  18. /*Clear IO*/
  19. PORTB=0x00;
  20. PORTD=0x00;
  21. /*Port B input*/
  22. TRISB=0xFF;
  23. /*Turn on Weak Pull Up*/
  24. OPTION_REGbits.nRBPU=0;
  25. /*Port C output*/
  26. TRISD=0x00;
  27. while(1){
  28. PORTD=PORTB;
  29. for(int i=0;i<25;i++);
  30. }
  31. }

 Click here to download this example is zip format. 



Port A

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.

PIC16F877A Basic Digital I/O Port Programming
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.

Schematic diagram and its simulation

Port A is usable only five bits. So I mask other two remaining MSB.

  1. /*
  2.  * PIC16F877A Port A Programming Example in XC8
  3.  */
  4. #include <xc.h>
  5.  
  6. // PIC16F877A Configuration Bit Settings
  7. // CONFIG
  8. #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
  9. #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
  10. #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
  11. #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
  12. #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)
  13. #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
  14. #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
  15. #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
  16.  
  17. void main(void){
  18. /*Clear IO*/
  19. PORTB=0x00;
  20. PORTA=0x00;
  21. /*Port A input*/
  22. TRISA=0xFF;
  23. /*Disable ADC input*/
  24. ADCON1=0x06;
  25. /*Port B output*/
  26. TRISB=0x00;
  27. while(1){
  28. /*Read Port A input*/
  29. PORTB=PORTA&0b00111111;
  30. /*A little delay*/
  31. for(int i=0;i<10;i++);
  32. }
  33. }

 Click here to download this example program.

 

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)