# pic 16f877a 7 segment multiplexing problems

Discussion in 'Embedded Systems and Microcontrollers' started by thedarkotaku, Oct 10, 2012.

1. ### thedarkotaku Thread Starter New Member

Feb 28, 2011
7
0
hello again everyone.

I've been trying for the past couple days to get a six digit counter working via a pic16f877a, I downloaded an example from here:

http://www.mikroe.com/chapters/view/17/chapter-4-examples/#c4v11

I've been attempting to get at least a 4 digit counter for now and then work my way up to 6.
heres what I have right now due to someone suggesting that I try it that way:

http://www.sendspace.com/file/x2y2td

as far as I can see, even with modifying digit_no = at the end of each case, nothing visible occurs.

I've also done it up this way:

http://www.sendspace.com/file/thagu9

it seems theres something im missing.

the original example works without problems on my chip, I would think modifying it to suit my needs should work. if anyone has any ideas or corrections or could catch something I missed i'd appreciate it , thanks

2. ### thedarkotaku Thread Starter New Member

Feb 28, 2011
7
0
ive even just now done this:

unsigned short digit_no,digit1000,digit100, digit10, digit1, digit, i;
void interrupt() {
if (digit_no==0) {
PORTA = 0; // Turn off all displays
PORTB = digit1; // Set mask for displaying ones on PORTD
PORTA = 1; // Turn on display for ones
digit_no = 1;
} else if(digit_no==1){
PORTA = 0; // Turn off all displays
PORTB = digit10; // Set mask for displaying tens on PORTD
PORTA = 2; // Turn on display for tens
digit_no = 2;
} else if(digit_no==2){
PORTA = 0;
PORTB = digit100;
PORTA = 3;
digit_no = 3; // Turn on display for hundreds
} else if(digit_no==3){
PORTA = 0;
PORTB = digit1000;
PORTA = 4; // Turn on display for thousands
digit_no = 0;
}
TMR0 = 0; // Reset counter TMRO
INTCON = 0x20; // Bit T0IF=0, T0IE=1
}
void main() {
OPTION_REG = 0x80; // Set timer TMR0
TMR0 = 0;
INTCON = 0xA0; // Disable interrupt PEIE,INTE,RBIE,T0IE
PORTA = 0; // Turn off all displays
TRISA = 0; // All port A pins are configured as outputs
PORTB = 0; // Turn off all display segments
TRISB = 0; // All port D pins are configured as outputs
do {
for (i = 0; i<=9999; i++) { // Count from 0 to 9999
digit = i % 10u;
digit = (char)(i / 10u) % 10u;
digit = (char)(i / 100u) % 10u;
digit = (char)(i / 1000u) % 10u;
Delay_ms(1000);
}
} while (1); // Endless loop
}
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x3F;
case 1 : return 0x06;
case 2 : return 0x5B;
case 3 : return 0x4F;
case 4 : return 0x66;
case 5 : return 0x6D;
case 6 : return 0x7D;
case 7 : return 0x07;
case 8 : return 0x7F;
case 9 : return 0x6F;
}
}

and still nothing happens. anybody know what i'm doing wrong?

3. ### ErnieM AAC Fanatic!

Apr 24, 2011
7,335
1,573
Besides not using code tags?

Besides not posting a schematic?

Nope, not a clue.

4. ### MMcLaren Well-Known Member

Feb 14, 2010
756
115
Please correct me if I'm wrong, but, I suspect you've connected the third and fourth digit column drivers to the RA2 and RA3 pins. If that's the case, you need to fix the statements that enable those digits;

Code ( (Unknown Language)):
1. unsigned short mask(unsigned short num);
2. unsigned short digit_no,digit1000,digit100, digit10, digit1, digit, i;
3.
4. void interrupt() {
5.   if (digit_no==0) {
6.     PORTA = 0; // Turn off all displays
7.     PORTB = digit1; // Set mask for displaying ones on PORTD
8.     PORTA = 1; // Turn on display for ones (RA0 = 1)
9.     digit_no = 1;
10.   } else if(digit_no==1) {
11.     PORTA = 0; // Turn off all displays
12.     PORTB = digit10; // Set mask for displaying tens on PORTD
13.     PORTA = 2; // Turn on display for tens (RA1 = 1)
14.     digit_no = 2;
15.   } else if(digit_no==2){
16.     PORTA = 0;
17.     PORTB = digit100;
18.     PORTA = 4; // Turn on display for hundreds (RA2 = 1)
19.     digit_no = 3; // Turn on display for hundreds
20.   } else if(digit_no==3){
21.     PORTA = 0;
22.     PORTB = digit1000;
23.     PORTA = 8; // Turn on display for thousands (RA3 = 1)
24.     digit_no = 0;
25.   }
26.   TMR0 = 0; // Reset counter TMRO
27.   INTCON = 0x20; // Bit T0IF=0, T0IE=1
28. }
29.
30. void main() {
31.   OPTION_REG = 0x80; // Set timer TMR0
32.   TMR0 = 0;
33.   INTCON = 0xA0; // Disable interrupt PEIE,INTE,RBIE,T0IE
34.   PORTA = 0; // Turn off all displays
35.   TRISA = 0; // All port A pins are configured as outputs
36.   PORTB = 0; // Turn off all display segments
37.   TRISB = 0; // All port D pins are configured as outputs
38.   do {
39.     for (i = 0; i<=9999; i++) { // Count from 0 to 9999
40.       digit = i % 10u;
42.       digit = (char)(i / 10u) % 10u;
44.       digit = (char)(i / 100u) % 10u;
46.       digit = (char)(i / 1000u) % 10u;
48.       Delay_ms(1000);
49.     }
50.   } while (1); // Endless loop
51. }
52.
53. unsigned short mask(unsigned short num) {
54.   switch (num) {
55.   case 0 : return 0x3F;
56.   case 1 : return 0x06;
57.   case 2 : return 0x5B;
58.   case 3 : return 0x4F;
59.   case 4 : return 0x66;
60.   case 5 : return 0x6D;
61.   case 6 : return 0x7D;
62.   case 7 : return 0x07;
63.   case 8 : return 0x7F;
64.   case 9 : return 0x6F;
65.   }
66. }
67.
Please let us know how you're doing.

Cheerful regards, Mike

5. ### thedarkotaku Thread Starter New Member

Feb 28, 2011
7
0
well I've done this:

unsigned short digit_no,digit1000,digit100, digit10, digit1, digit, i;
void interrupt() {
if (digit_no==0) {
PORTA = 0; // Turn off all displays
PORTB = digit1; // Set mask for displaying ones on PORTD
PORTA = 0; // Turn on display for ones
digit_no = 1;
} else if(digit_no==1){
PORTA = 0; // Turn off all displays
PORTB = digit10; // Set mask for displaying tens on PORTD
PORTA = 1; // Turn on display for tens
digit_no = 2;
} else if(digit_no==2){
PORTA = 0;
PORTB = digit100;
PORTA = 2;
digit_no = 3; // Turn on display for hundreds
} else if(digit_no==3){
PORTA = 3;
PORTB = digit1000;
PORTA = 2; // Turn on display for thousands
digit_no = 0;
}
TMR0 = 0; // Reset counter TMRO
INTCON = 0x20; // Bit T0IF=0, T0IE=1
}
void main() {
OPTION_REG = 0x80; // Set timer TMR0
TMR0 = 0;
INTCON = 0xA0; // Disable interrupt PEIE,INTE,RBIE,T0IE
PORTA = 0; // Turn off all displays
TRISA = 0; // All port A pins are configured as outputs
PORTB = 0; // Turn off all display segments
TRISB = 0; // All port D pins are configured as outputs
do {
for (i = 0; i<=9999; i++) { // Count from 0 to 9999
digit = i % 10u;
digit = (char)(i / 10u) % 10u;
digit = (char)(i / 100u) % 10u;
digit = (char)(i / 1000u) % 10u;
Delay_ms(1000);
}
} while (1); // Endless loop
}
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x3F;
case 1 : return 0x06;
case 2 : return 0x5B;
case 3 : return 0x4F;
case 4 : return 0x66;
case 5 : return 0x6D;
case 6 : return 0x7D;
case 7 : return 0x07;
case 8 : return 0x7F;
case 9 : return 0x6F;
}
}

nothing is lighting up. even went so far as to try it on my spares and nothing. I have the segments output to port B and the commons on ra0 thru 3. why is this thing giving me so much grief? I tried it with two and it worked just fine.

I've googled this for two weeks now without anything solid, I've tried dozens of examples page after page of google searching. is there perhaps another way to go about this? my goal is six of them. I had two working I thought doubling or tripling that would be doable.

Last edited: Oct 10, 2012