Multiplexing Seven Segment Displays

Thread Starter

yuanshikai

Joined Sep 17, 2011
49
Hello,

I have read about multiplexing seven segment displays and I believe I understood it's theory. That the individual digits of the seven segment display should be turned on alternately with a very small refresh rate so that persistence of vision causes the numbers to appear steady. I created a code with mikroC and a simulation circuit with Proteus Isis.

However, the display didn't turn out as expected. I observed that even when I already deactivate my transistor (BC557), it would still conduct for approximately 1 second - keeping it's display turned on in the process. This totally messes with the program and if I set the refresh delays for alternately turning on the displays to be very small (50ms), both displays would be turned on all the time. I need to set the delay to at least be 1300ms to make the theory of multiplexing work in which the displays are turned on one at a time. I can't seem to figure it out what I did wrong.

I have attached an image of my circuit and the C code. My circuit is supposed to be a coinslot but the problem I'm having is only on the seven segment displays. You can disregard the other parts of the circuit. I hope you guys can help me with this.



Code:

void display(int number)
{
int digit1, digit2;
digit1 = number/10;
digit2 = number%10;
portb.f6 = 1;
portb.f7 = 1;
switch (digit1)
{
case 1: { porta = 0xC9; portb.f4 = 1; portb.f5 = 1; break;}
case 2: { porta = 0x84; portb.f4 = 0; portb.f5 = 1; break;}
case 3: { porta = 0x80; portb.f4 = 1; portb.f5 = 1; break;}
case 4: { porta = 0x89; portb.f4 = 1; portb.f5 = 0; break;}
case 5: { porta = 0x82; portb.f4 = 1; portb.f5 = 0; break;}
case 6: { porta = 0x82; portb.f4 = 0; portb.f5 = 0; break;}
case 7: { porta = 0xC8; portb.f4 = 1; portb.f5 = 1; break;}
case 8: { porta = 0x80; portb.f4 = 0; portb.f5 = 0; break;}
case 9: { porta = 0x88; portb.f4 = 1; portb.f5 = 0; break;}
case 0: { porta = 0x80; portb.f4 = 0; portb.f5 = 0; break;}

}
portb.f6 = 0;
Delay_ms(50);
portb.f6 = 1;
Delay_ms(50);
switch (digit2)
{
case 1: { porta = 0xC9; portb.f4 = 1; portb.f5 = 1; break;}
case 2: { porta = 0x84; portb.f4 = 0; portb.f5 = 1; break;}
case 3: { porta = 0x80; portb.f4 = 1; portb.f5 = 1; break;}
case 4: { porta = 0x89; portb.f4 = 1; portb.f5 = 0; break;}
case 5: { porta = 0x82; portb.f4 = 1; portb.f5 = 0; break;}
case 6: { porta = 0x82; portb.f4 = 0; portb.f5 = 0; break;}
case 7: { porta = 0xC8; portb.f4 = 1; portb.f5 = 1; break;}
case 8: { porta = 0x80; portb.f4 = 0; portb.f5 = 0; break;}
case 9: { porta = 0x88; portb.f4 = 1; portb.f5 = 0; break;}
case 0: { porta = 0x80; portb.f4 = 0; portb.f5 = 0; break;}
}
portb.f7 = 0;
Delay_ms(50);
portb.f7 = 1;
Delay_ms(50);
}

void main() {

int Active, Account;
cmcon = 0x07;
TRISA = 0x30;
TRISB = 0x01;
Active = 1;
porta = 0xFF;
portb = 0xFF;

while(1){
Display(98);
}
}
 

LDC3

Joined Apr 27, 2013
924
Had you wired the segments to one port, it would have been easier to select the segments on the display.

I would first remove
portb.f6 = 1;
portb.f7 = 1;
from the subroutine since you set them in main().

Is porta.f4 or portb.f0 connected to anything? Is setting parta and portb to FF ok with the connections you have to the MCU?

It might be better to display 25 (instead of 98) so you can see if the problem is with one digit or both.
 

Thread Starter

yuanshikai

Joined Sep 17, 2011
49
I could have wired the segments to one port but it just isn't possible with my circuit. I need the UART pins on portb and the MCLR/A5 pin on porta cannot be configured as output.

For the redundancy in the code, that was just my paranoia while I was trying to debug the cause of my problem.

Setting both portA and portB to FF was also just part of my debugging process. And I already configured the pins to be input or output with the TRIS function. I set porta.f4 or portb.f0 to be inputs. If I equate these pins to logic 1 in the code, would these pins output high even though they're inputs?

I tried 25 and the problem definitely is with both. Please look at the second transistor below. These pnp transistors should only conduct when the voltage at the base is low. I activate the digits by setting the voltage to portb.f6 and portb.f7 to low alternately for 50ms. The moment of the image would be after the activation of the second digit. By this time, since the voltage at the base of the second transistor is high again, the digit should be turned off but it isn't. I need to delay 1300ms before the digit is finally turned off.

 

LDC3

Joined Apr 27, 2013
924
Sorry I missed that you set porta.f4 and portb.f0 to inputs. Also, it shouldn't matter if you change their settings in the program. At this time, I can't see any errors in the program.

Are you using an LED or an LCD?
Is it possible to add pull-up resistors to pins 12 and 13?
 

Thread Starter

yuanshikai

Joined Sep 17, 2011
49
LED. I added pull-up resistors as you suggested but it doesn't really affect it significantly. Is there really something like a turn-off delay for transistors?
 

absf

Joined Dec 29, 2010
1,968
I have the same problem with Proteus. Try to add 2x 10K resistors to the collectors of Q2 and Q3 to GND and see if it works.

The circuit should work in real world but not in proteus.

Allen
 

Thread Starter

yuanshikai

Joined Sep 17, 2011
49
I have the same problem with Proteus. Try to add 2x 10K resistors to the collectors of Q2 and Q3 to GND and see if it works.

The circuit should work in real world but not in proteus.

Allen
Whoa. It works. Thank you.

But if I am to create this circuit in the real world. Should I pick your design or stay with mine?
 

absf

Joined Dec 29, 2010
1,968
The circuit should work in real world but not in proteus.
Actually, I meant "your circuit should work in real world" without the 2 resistors.

Proteus have other minor problems like :- it is not able to oscillate if you construct a two-transistor-astable-multi-vibrator. So I have to use the "pulse source" in the toolbox. The more you play with it the more you'll learn.

Allen
 
Top