In previous post I wrote about Port B interrupt on change. Now I show a programming example using this interrupt and multiplexing display.
In this example, Two input button increase and decrease the counting value. Two digits multiplexing display shows its counting content. These two buttons use the interrupt on change of Port B. They don't need to connects to external pull up resistors. Internal weak pull up resistors of Port B are in use.
XC8 Programming
/* * PIC16F877a Port B Interrupt On Change * And Multiplexing Display Example */ #include <xc.h> // PIC16F877A Configuration Bit Settings // CONFIG #pragma config FOSC = HS #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config BOREN = ON #pragma config LVP = OFF #pragma config WRT = OFF #pragma config CP = OFF #define _XTAL_FREQ 20e6 unsigned char cnt=0; /*Multiplexing display routine*/ void driveDisplay(void){ char cCathode[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; PORTC=0x00; PORTD=cCathode[cnt/10]; RC0=1; __delay_ms(5); PORTC=0x00; PORTD=cCathode[cnt%10]; RC1=1; __delay_ms(5); } void main(void){ /*Clear IO port*/ PORTB=0x00; PORTC=0x00; PORTD=0x00; /*RB4...7 input*/ TRISB=0xF0; /*Port C and Port D output*/ TRISC=0x00; TRISD=0x00; /*Turn on Pull Up Resistor*/ nRBPU=0; /*Turn On External Interrupt*/ RBIE=1; /*Turn On Global Interrupt*/ GIE=1; /*Clear Interrupt Flag*/ RBIF=0; while(1){ driveDisplay(); } } /*Interrupt Service Routine*/ void interrupt portBChange(void){ /*Check RB Port Change Interrupt Present*/ if(RBIE&&RBIF){ if(RB6^1) { if(cnt<99) cnt++; } if(RB7^1){ if(cnt>0) cnt--; } RBIF=0; } }
Schematic Diagram
Schematic Diagram |
Click here to download source file. We can use a serial to parallel shift registers IC to drive this kind of display.