pic 16f877a 7 segment multiplexing problems

Thread Starter

thedarkotaku

Joined Feb 28, 2011
7
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 :)
 

Thread Starter

thedarkotaku

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

unsigned short mask(unsigned short num);
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;
digit1 = mask(digit); // Prepare mask for displaying ones
digit = (char)(i / 10u) % 10u;
digit10 = mask(digit);
digit = (char)(i / 100u) % 10u;
digit100 = mask(digit);
digit = (char)(i / 1000u) % 10u;
digit1000 = mask(digit);
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?
 

MMcLaren

Joined Feb 14, 2010
861
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;

Rich (BB code):
unsigned short mask(unsigned short num);
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 (RA0 = 1)
    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 (RA1 = 1)
    digit_no = 2;
  } else if(digit_no==2){
    PORTA = 0;
    PORTB = digit100;
    PORTA = 4; // Turn on display for hundreds (RA2 = 1)
    digit_no = 3; // Turn on display for hundreds
  } else if(digit_no==3){
    PORTA = 0;
    PORTB = digit1000;
    PORTA = 8; // Turn on display for thousands (RA3 = 1)
    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;
      digit1 = mask(digit); // Prepare mask for displaying ones
      digit = (char)(i / 10u) % 10u;
      digit10 = mask(digit);
      digit = (char)(i / 100u) % 10u;
      digit100 = mask(digit);
      digit = (char)(i / 1000u) % 10u;
      digit1000 = mask(digit);
      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;
  }
}
Please let us know how you're doing.

Cheerful regards, Mike
 

Thread Starter

thedarkotaku

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

unsigned short mask(unsigned short num);
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;
digit1 = mask(digit); // Prepare mask for displaying ones
digit = (char)(i / 10u) % 10u;
digit10 = mask(digit);
digit = (char)(i / 100u) % 10u;
digit100 = mask(digit);
digit = (char)(i / 1000u) % 10u;
digit1000 = mask(digit);
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:
Top