# [SOLVED]Multiplexed 7segment display simulation problem in proteus

#### Mithun_K_Das

I had several 7segment based meters which works fine in hardware. Most of these are regular products, no display problem found yet in last 7yrs+.
Today, I was trying to make a simple simulation based on 7segment display in proteus 8.9. But I found that, it can not display 7segment properly.
Either it shows still non-digits or flickering. I tried changing timing for multiplexing. But can't find the problem.

Can anyone tell me whats wrong here? Again I'm mentioning that, it works in hardware with this 5ms refresh interval. Sometimes little adjustment may required.
It is not working properly in proteus only.

Here is the simplified code which I was testing.

Code:
unsigned short mask(int num)
{
switch (num)
{
case 0 : return 0xC0;
case 1 : return 0xF9;
case 2 : return 0xA4;
case 3 : return 0xB0;
case 4 : return 0x99;
case 5 : return 0x92;
case 6 : return 0x82;
case 7 : return 0xF8;
case 8 : return 0x80;
case 9 : return 0x90;
}
}
unsigned short  portb_index;
unsigned int digit,number;
unsigned short portb_array[5];

void display_digits()
{
PORTB = portb_array[portb_index];
if(portb_index==3)
{
RC0_bit = 1;
RC1_bit = 0;
RC2_bit = 0;
RC3_bit = 0;
}
if(portb_index==2)
{
RC0_bit = 0;
RC1_bit = 1;
RC2_bit = 0;
RC3_bit = 0;
}
if(portb_index==1)
{
RC0_bit = 0;
RC1_bit = 0;
RC2_bit = 1;
RC3_bit = 0;
}
if(portb_index==0)
{
RC0_bit = 0;
RC1_bit = 0;
RC2_bit = 0;
RC3_bit = 1;
}
portb_index ++ ;
Delay_ms(5);
if (portb_index > 3)portb_index = 0;
}

void Digit_seperation()
{
digit = (number / 1u) % 10u;
digit = (number / 10u) % 10u;
digit = (number / 100u) % 10u;
digit = number / 1000u;
}

void main()
{
TRISA = 0xFF; // all input.
TRISB = 0x00; // Set PORTB direction to be output
TRISC = 0x00; // Set PORTB direction to be output
PORTC = 0x00;
PORTB = 0x00;
while(1)
{

number = 5432;
Digit_seperation();
display_digits();

}//Endless loop;
}//End.

// end

And the proteus file:

- - - Updated - - -

This is happening most of the time.

#### Attachments

• 16.4 KB Views: 2

#### betwixt

##### Super Moderator
Staff member
Ugh!
Please use a timer to set the multiplexing rate, it is the only way you will get the digits to have equal brightness. Ideally, use a timer to create an interrupt and cycle through the digits at each call to the ISR.

Why are you using that switch/case statement when a simple array would suffice and take up far less space, and more importantly a constant time to execute regardless of the index?

Brian.

#### FvM

##### Super Moderator
Staff member
1. Delay_ms() statement isn't simulated in real time. Your code has to be corrected for this fact.
2. Muxed LCD component in Proteus is working as a one shot with configurable pulse width. The parameter can be adjusted.
3. Your display_digits() procedure has a fault that might not show in real hardware. You need to disable the digit driver first, then write the new segment value, then enable the new digit.

#### Mithun_K_Das

In main program I used timer. As it was not working properly, I simplified the code to check if there is any mistake in timer ISR. With timer ISR, it work fine in real hardware. But that same code in simulation can not display segment properly.

Switch-case issue: This code was first developed in around 2010. As it is not making any trouble so I did not changed later. If array consume less memory, I'll change to array.

Muxed LCD component: I tried changing the response time; Either it shows in flickering, or in non-digit. Even I've collected one ready file from libstock.com to check. It is also not displaying properly. I've attached the video here.
Also file is attached here:

- - - Updated - - -

The other simulation file in the last uploaded project file works.

#### Attachments

• 64.8 KB Views: 1

#### betwixt

##### Super Moderator
Staff member
For clarification - are you using 7-segment LEDs or LCDs? They require completely different drive signals, the code and schematic are for LEDs but your text mentions "Muxed LCD component".

I can't verify your simulation, Proteus only runs under Windows.

Brian.

#### Mithun_K_Das

Oh sorry, Muxed LCD component may be wrong. It should be LED for sevensegment. I copied from previous post of FVM.

Anyway, I solved this problem.

There was a timing problem for Data pins in interrupt ISR.

Finally modified code:
Code:
char segment_array[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6  F};//cmmon cathode_non dot

sbit digit0 at RC0_bit;
sbit digit1 at RC1_bit;
sbit digit2 at RC2_bit;
sbit digit3 at RC3_bit;

char digits[5];
void display_7segment(int number)
{
digits[3]=number/1000u;
digits[2]=(number/100u)%10u;
digits[1]=(number/10u)%10u;
digits[0]=(number/1u)%10u;
}

void InitTimer0()
{
OPTION_REG     = 0x85;
TMR0           = 100;
INTCON         = 0xA0;
}

int position=0;
void Interrupt() iv 0x0004 ics ICS_AUTO
{
if (TMR0IF_bit)
{
TMR0IF_bit   = 0;
TMR0         = 100;

digit0 = 1;
digit1 = 1;
digit2 = 1;
digit3 = 1;
if(position>3)position=0;

if(position==1)PORTB = segment_array[digits[position]]+128; //dot point
else PORTB = segment_array[digits[position]];

if(position==3)
{
digit0 = 0;
digit1 = 1;
digit2 = 1;
digit3 = 1;
}
else if(position==2)
{
digit0 = 1;
digit1 = 0;
digit2 = 1;
digit3 = 1;
}
else if(position==1)
{
digit0 = 1;
digit1 = 1;
digit2 = 0;
digit3 = 1;
}
else if(position==0)
{
digit0 = 1;
digit1 = 1;
digit2 = 1;
digit3 = 0;
}
position++;
}
}

unsigned int cnt=0;
void main()
{
TRISB=0x00;//all output
TRISC=0x00;//all output
PORTB=0x00;
PORTC=0x00;//clear ports
InitTimer0();//5ms timer
while(1)
{

display_7segment(cnt);
cnt++; Delay_ms(200);
if(cnt>9999)cnt=0;
}
}

//
- - - Updated - - -

If you have any further suggestion for this code to make it more professional please share. Thanks.

#### betwixt

##### Super Moderator
Staff member
Technically you shouldn't enable the GIE bit in INTCON at the same time as the interrupt itself but it wouldn't make any difference the performance in your program.

You can further simplify it by using an array for the digit drive signals as well and in real life you probably need to allow for some 'dead' time between digits, a brief period when all the segments are turned off before setting the next pattern, or you may see some 'ghosting'. A trick here is to combine the two suggestions, by turning all the digits off before changing the segments then turning the new digit on.

Brian.