Interfacing PIC Microcontroller With 7 Segment Display - MikroC Code
Interfacing PIC Microcontroller With 7 Segment Display - MikroC Code
Projects
In this project a PIC16F887 microcontroller is interfaced with 7-segment
display in order to build a simple 4-digit counter which counts from 0 to
9999. A push button connected to the PIC16F887 MCU is used to
increment the displayed number.
The compiler used for this project is mikroC PRO for PIC.
There are two types of the seven-segment displays: common anode and
common cathode.In the common anode type all the 7 LED anode terminals
are connected together whereas in the common cathode all cathode
terminals are connected together.
Basically, for each 7-segment digit there are 8 pins: one for the common
terminal (anode or cathode) and 7 pins for the 7 segments (A, B, C, D, E, F
and G). Another pin may be used for the decimal point (DP).
In multi-digit 7-segment display (for example 4-digit) all pins of the same
segment are connected together (segment A of digit 1 with segment A of
digit 2 …), and each digit has its common pin alone. This is called
multiplexing technique. This technique minimizes number of pins used.
1
So, for a 4-digit display we’ll have 7 pins of the 7 segments, 4 pins of the 4
digits (common terminals) and 1 pin for the decimal point (DP) which
means a total of 12 pins.
Hardware Required:
PIC16F887 microcontroller —-> datasheet
4-digit common anode 7-segment display
4 x PNP transistor (2SA1015, 2S9015, 2N3906 …)
7 x 100 ohm resistor
4 x 4.7k ohm resistor
Push button
5V source
Breadboard
Jumper wires
2
current because the PIC16F887 microcontroller may not be able to
do that (maximum output current is 25 mA).
Each transistor emitter pin is connected to +5V and each transistor
base is connected to the PIC16F887 through 4.7k resistor as follows:
digit 1 (most left) transistor base is connected to PIC16F887 pin RB3
(#36)
digit 2 transistor base is connected to PIC16F887 pin RB2 (#35)
digit 3 transistor base is connected to PIC16F887 pin RB1 (#34)
digit 4 (most right) transistor base is connected to PIC16F887 pin
RB0 (#33)
Each 100 ohm resistor is used for limiting the current that passes
through the segment LED.
The push button which is connected to PIC16F887 pin RB4 (#37) is
used to increment the displayed number.
A common anode 7-segment display is used in this example.
In this project the PIC16F887 microcontroller runs with its internal
oscillator @ 8 MHz, MCLR pin is configured as an input pin.
Since the 4 digits are multiplexed the display must be refreshed very
quickly (display one digit at a time, others are off). For that Timer0
module (8-bit timer) interrupt with 1:16 prescaler was used; this
means Timer0 overflows every 2048 microseconds { 256/[8/(4 x 16)]
= 256 x 8 = 2048 microseconds }.
3
*******************************************************************************
*******
Interfacing PIC16F887 with common anode 7-segment display.
4-Digit counter example.
C Code for mikroC PRO for PIC compiler.
Internal oscillator used @ 8MHz
Configuration words: CONFIG1 = 0x2CD4
CONFIG2 = 0x0700
This is a free software with NO WARRANTY.
http://simple-circuit.com/
*******************************************************************************
********/
unsigned short current_digit;
int count = 0;
void disp(unsigned short number)
{
switch (number)
{
case 0: // print 0
PORTD = 0x02;
break;
case 1: // print 1
PORTD = 0x9E;
break;
case 2: // print 2
PORTD = 0x24;
break;
case 3: // print 3
PORTD = 0x0C;
break;
case 4: // print 4
PORTD = 0x98;
break;
case 5: // print 5
PORTD = 0x48;
break;
case 6: // print 6
PORTD = 0x40;
break;
case 7: // print 7
PORTD = 0x1E;
break;
case 8: // print 8
PORTD = 0x00;
break;
case 9: // print 9
PORTD = 0x08;
}
4
}
void interrupt()
{
PORTD = 0xFE; // turn off all segments
if(current_digit == 1){
PORTB = 0x07; // turn on digit 1 (most left)
disp(count / 1000);
}
if(current_digit == 2){
PORTB = 0x0B; // turn on digit 2
disp((count / 100) % 10);
}
if(current_digit == 3){
PORTB = 0x0D; // turn on digit 3
disp((count / 10) % 10);
}
if(current_digit == 4){
PORTB = 0x0E; // turn on digit 4 (most right)
disp(count % 10);
}
current_digit = (current_digit % 4) + 1;
T0IF_bit = 0; // clear Timer0 interrupt flag bit
}
void main()
{
OSCCON = 0x70; // set internal oscillator to 8MHz
ANSELH = 0; // configure all PORTB pins as digital
PORTB = 0;
TRISB = 0xF0; // configure RB0, RB1, RB2 & RB3 as outputs
PORTD = 0;
TRISD = 0;
TMR0 = 0; // reset Timer0
OPTION_REG = 0x03; // set Timer0 prescaler to 1:16
INTCON = 0xA0; // enable global interrupt & Timer0 overflow interrupt
WPUB4_bit = 1; // enable RB4 internal weak pull-up
while(1)
{
if(PORTB.F4 ==0)
{ // if button is pressed
count++; // increment 'count' by 1
if(count > 9999)
count = 0;
delay_ms(200); // wait 200 milliseconds
}
}
}
// end of code.