Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

multiplex two 7 segment display using pic16f877

Status
Not open for further replies.

ho907

Junior Member level 1
Joined
Mar 2, 2010
Messages
15
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,400
hi,,
i am having problem with multiplexing two common anode 7 segment displays. i am using pic16f877. i am trying to implement a decimal counter 0-99. i can use one 7 segment display to show 1-9 but i do not know how to use two using multiplexing.
i am using mikroC pro and c prohramming language.
help needed urgently.....plzz
plz help me with some simple code for using two displays as i already know how to use one..
thanks
 

thankx for reply..my code is below. it is checked on the hardware and is working fine. the 7 segment display increments once a second and shows 0-9. but i need 2 displays to show 00-99. plz give me any link or source code for c language, not assembly...


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void main() {
TRISB = 0x00;    // port B as output
PORTB = 0x00;    //clear portB
while (1)
{
PORTD. RD1 = 1;
PORTB = 0b1111001;    //1 on 7 segment
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0100100;    //2 on 7 segment
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0110000;    //3 on 7 segment
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0011001;    //4
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0010010;    //5
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0000010;    //6
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b1111000;    //7
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0000000;    //8
Delay_ms(1000);
PORTD. RD1 = 1;
PORTB = 0b0010000;    //9
Delay_ms(1000);
 
}
}

 
Last edited by a moderator:

Maybe can help

I'm using avr only.
In general what i do is

define an array
char display_digit[10]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0xbf,0x7f}
in which i define the digits 0..9
for example to light the number 5 i do PORTX =display_digit[5] , or for 0 PORTX =display_digit[0] etc

for you this would be
char display_digit[10]={0b1111001,0b0100100,0b0110000,0b0011001,0b0010010,0b0000010,0b1111000,0b0000000,0b0010000}
or convert it to the hex values if you want

then i define an array of 2 char.
char my_number[2];

i store the two numbers i want in this array, for example for 25
my_number[0]=2;
my_number[1]=5;


When you want to show the first digit you use
PORTB = display_digit[ my_number[0] ]
and for the second number
PORTB = display_digit[ my_number[1] ]

all you have to do now is to connect the 7 segments of the display together and use each enable (the common supply) of the led to a different pin in another port (use transistors as the link i gave before).
Now you can use either a loop, or a delay or a timer to do the following

enable led 1
show value 1
enable led 2
show value 2

and is also very easy to extend this kind of code to use 3 or 4 or more displays
Hope this helps

Alex
 
dear....
i tried it with the code. but the problem is still on multiplexing. though i can lit one display and show digits but i cant show two different digits on two displays. plz clarify the multiplexing bit either using loop or timer. i tried it using delay_ms function but then the displays turn on one after another. then i used short delay of 10ms but then none of the displays turn on. i tried upto 50ms but still the same. at 100ms delay the displays blink just like a blinking led...
plz provide me with some c code...its taking my life
 

Are your displays common anode (common +) or common cathode (common gnd)?
Did you make the connection as i said to enable 1 display at a time like https://melabs.com/images/ledfig6.gif

i normally use a timer interrupt but you can also do it in whle loop

Code:
while (1)
{

[B]write the code here to enable the display 1 and disable display 2[/B] 
PORTB = display_digit[ my_number[0] ]
delay_ms(20)
[B]write the code here to enable the display 2 and disable display 1 [/B] 
PORTB = display_digit[ my_number[1] ]
delay_ms(20)
}

If it doesn't work , post your code to see what you are doing wrong

Alex

---------- Post added at 17:18 ---------- Previous post was at 17:12 ----------

maybe you don't understand what multiplexing is, there is only one display on at a given time but because you turn on/of the displays at a speed above 50 time/sec the eye thinks that both are on all the time.
 

hi alex...
thanks for ur help mate.. im using common anode displays at RD0 and RD1 pins. i connected everything as on the link but still no result. the displays are blinking one after another. can u plz show me the way of using timer.. my code is below..
thanks


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
char display_digit[9]= {0b1111001,0b0100100,0b0110000,0b0011001,0b0010010,0b0000010,0b1111000,0b0000000,0b0010000};
void main() {
TRISD = 0x00;
TRISB = 0x00;    // port B as output
PORTB = 0x00;    //clear portB
while (1)
{
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[1];    //1
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[2];    //2
Delay_ms(20);
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[3];    //3
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[4];    //24
Delay_ms(20);
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[5];    //5
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[6];    //6
Delay_ms(20);
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[7];    //7
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[8];    //8
Delay_ms(20);
 
}
}

 
Last edited by a moderator:

I can't tell you how to use timers in pic, i only use AVR.
You are changing the number that is displayed every 20ms, this is wrong , if you want to change the showing number you should do it at a much slower rate so that the eye can see it first.
The following code will show the number 12
also play with the 20ms delay, to 200ms or 500ms to see exactly how it works
the delay_ms() is a function of avr_gcc, does it work for you?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
char display_digit[9]= {0b1111001,0b0100100,0b0110000,0b0011001,0b0010010 ,0b0000010,0b1111000,0b0000000,0b0010000};
void main() {
TRISD = 0x00;
TRISB = 0x00; // port B as output
PORTB = 0x00; //clear portB
while (1)
{
PORTD. RD0 = 1; //eneble segment 1
PORTD. RD1 = 0; //disable segment 2
PORTB = display_digit[1]; //1
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[2]; //2
Delay_ms(20);
}
}


Alex
 
i know mate u r working for me... i tried this and ur code shows 12 all right but the displays turns on one after another like blinking. if i reduce the delay the displays dont show anything and if delay is increased the displays blink slowly..
another question is how im gonna show 13 after12, the 14, then 15... at one second delay??
 

How much did you reduce the delay?
try with 15ms or 10ms
For accurate time you need an interrupt but just for the fun of it you can use a variable that counts and increases the number every second.
for example if your delays are 20+20ms= 40ms you can make a counter in the start of the loop that adds 1 every 25 loops, if it is set to 10+10ms then every 50 loops.
When the second digit counts 10 you should add one to the first digit;
I say again that this will not be accurate.

Alex
 

Frnds can u help me by letting me knw that how can one code PIC 16F877A using C or Mikro C to count from 99-0 secs!!I am using 8 way dip switch for input!!using C I can get the output across PORT B but the problem is that i am using simple LEDS which is quite simple!!But i want to show the countdown using 7 segment displays (2) without having to use any decoder......I need to get a code or atleast understand the logic in C of getting the numericals displayed on 7 segment without any help of any device except of PIC 16F877A!

I got the idea of masking the numbers one by one from 1-9!!bt that process seems lengthy and confusing!!can u plz help me by figuring out any other method of displaying the digits (00-99) on 7 segment without using decoder or any device!!

Thanks a lot in advance!!I m new over here!
 

hi alex...
thanks for ur help mate.. im using common anode displays at RD0 and RD1 pins. i connected everything as on the link but still no result. the displays are blinking one after another. can u plz show me the way of using timer.. my code is below..
thanks


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
char display_digit[9]= {0b1111001,0b0100100,0b0110000,0b0011001,0b0010010,0b0000010,0b1111000,0b0000000,0b0010000};
void main() {
TRISD = 0x00;
TRISB = 0x00;    // port B as output
PORTB = 0x00;    //clear portB
while (1)
{
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[1];    //1
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[2];    //2
Delay_ms(20);
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[3];    //3
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[4];    //24
Delay_ms(20);
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[5];    //5
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[6];    //6
Delay_ms(20);
PORTD. RD0 = 1;   //eneble segment 1
PORTD. RD1 = 0;   //disable segment 2
PORTB = display_digit[7];    //7
Delay_ms(20);
PORTD. RD0 = 0;
PORTD. RD1 = 1;
PORTB = display_digit[8];    //8
Delay_ms(20);
 
}
}


First you have to initialize the timer in coding... By using timer interrupt you can switch both dispalys fast as continious visual... here i put my code (CCS)... if you go through that you may get better idea...

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <16f877.h>
#device PIC16F877  ADC=10
#fuses HS,WDT,PROTECT
#use delay(clock=10000000)
 
//----------------------------------------------------------------//
 
#define digit_3   PIN_A1
#define digit_4   PIN_A2
 
//----------------------------------------------------------------//
void init(void);
 
//----------------------------------------------------------------//
byte const seg_value[15] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92, 0x82,0xf8,0x80,0x90,0xff};
 
int16 time_value=0;
int16 counter1=0;
int8 digit1=0,digit2=0,count=1;
 
//----------------------------------------------------------------//
main()   
{
 
    port_b_pullups(TRUE);
 
//----------------------------------------------------------------//
 
    init();
    setup_wdt(WDT_2304MS);  
        while(TRUE)                             
        {
        
            }
}
//----------------------------------------------------------------//
void init(void)
 {
    set_tris_b(0x1f);
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); 
    set_timer1(0xF2Fb);                
    setup_adc(ADC_CLOCK_INTERNAL);
    set_adc_channel( 0 );
}
 
//****************************************************************
 
//***************************************************************
 
digit1=time_value/10;
digit2=time_value-(digit1*10);
 
//****************************************************************
}
//----------------------------------------------------------------//
#INT_TIMER1
void disp_isr() 
{
set_timer1(0xf2fb);    //Initialaize timer Ms                      
 
output_d(0xff);
switch(count)                           
{
case 1:
output_bit(digit_3,0);
output_bit(digit_4,1);
output_c(seg_value[digit1]);
count++;
break;  
case 2:
output_bit(digit_3,1);
output_bit(digit_4,0);
output_c(seg_value[digit2]);
count=1;
break;  
}
 
//**********************************************************************
 
counter1++;
 
 if(counter1==745)  //1 sec  
      { 
     counter1=0;
     time_value++;
   }
} 
else
  counter1=0;
  
//******************************************************************

 
Last edited by a moderator:

Thank you everyone. I was actually doing a wrong calculation on the delay. I have figured it out and my hardware is performing at its best. Thanks everyone for help. If anyone else needs help regarding this issue please contact me.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top