7 Segment 3 Digit Display Problem

Thread Starter

beeson76

Joined Apr 19, 2010
211
Hello everyone.

I am doing just a simple project to connect a 3 digit LED display to a PIC16F690 using the PICKIT 2 development board from Microchip.

The program just counts up every second. I would first like to stick with the first digit, and when I get to ten jump to the second digit etc.

I program the chip and on the 3 digit display it counts up, but all digits count instead of just one. I have all three digit pins grounded. I have tried to "shut off" the pins in the program but still to no avail.

By the way, it is a common cathode display. It is made by Fairchild MST4141C. It is kinda hard to find the datasheet because it looks like Fairchild was bought by Everlight I believe.

Here is the simple program.

Rich (BB code):
#include <htc.h>

int ones = 0b00010000;
int tens = 0b00100000;
int hundreds = 0b01000000;
int zero = 0b00000000;
int one = 0b00000110;
int two = 0b01011011;
int three = 0b01001111;
int four = 0b01100110;
int five = 0b01101101;
int six = 0b01111100;
int seven = 0b00000111;
int eight = 0b01111111;
int nine = 0b01100111;

__CONFIG (INTIO & WDTDIS & MCLRDIS & UNPROTECT);

void pause (unsigned short usvalue);

main ()
{

unsigned char state_led = 0;

ANSEL = 0;
ANSELH = 0;
CM1CON0 = 0;
CM2CON0 = 0;

PORTB = 0xFF;
PORTC = 0x00;
TRISB = 0x00;
TRISC = 0x00;

while (1==1)

{
	state_led++;
	switch (state_led)
		{
			case 1:
				PORTC = ones;
				PORTB = one;
				break;
			case 2:
				PORTC = ones;
				PORTB = two;
				break;
			case 3:
				PORTB = ones;
				PORTC = three;
				break;
			case 4:
				PORTB = ones;
				PORTC = four;
				break;
			case 5:
				PORTB = ones; 
				PORTC = five;
				break;
			case 6:
				PORTB = ones;
				PORTC = six;
				break;
			case 7:
				PORTB = ones;
				PORTC = seven;
				break;
			case 8:
				PORTB = ones;
				PORTC = eight;
				break;
			case 9: 
				PORTB = ones;
				PORTC = nine;
				break;
			default:
				state_led = 0;
				PORTC = zero;
				break;
		}

		pause(1000);
}
}
Thanks for any help provided.
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
Yes. The datasheet shows that the left digit is digit 1 and the right digit is digit 3. I can get the display to "count" but all three digits count instead of just one digit.

Some questions:

To get digit 1 and 2 (Left digit and middle digit) to light, Do I have to "turn on" the digits to make them light or do they light automatically, and I have to turn them off? I know it probably depends on it being Common anode and Common cathode too.
 

Markd77

Joined Sep 7, 2009
2,806
I found the datasheet. The display has 8 pins for the segments and decimal point and 3 pins for the common cathodes.
With this display you have to multiplex, I'd recommend an NPN transistor between each common cathode and ground, with the bases connected to 3 PIC pins via resistors.
Also individual current regulating resistors on all the segment pins.
You turn each transistor on, one at a time, and output the required pins for segments of that digit. If you do it fast (I'd recommend at least 100Hz) they look like they are all lit.
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
Thanks Markd77. I appreciate very much your reply.

I have been reading a little about multiplexing and was hoping I wouldnt have to do it. But I guess I have to learn to do it sometime:)

I will work on getting the circuit put together right, and then I will work on the code.

If I understand multiplexing right, you alternate so fast that the eye pretty much thinks both are lit. Would I actually alternate between whole digits (all segments) or between individual digit segments?
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
Thanks again Markd77 for the reply. I am laying out a schematic of it and I will post it here to get your comments, thoughts, and suggestions. Thanks again. I will use as my 3 transistors 2N3904.
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
I know its been awhile but I finally got my Schematic done. I don't yet have values on the current limiting resistors or the resisters tying the Microchip to the Transistors, but I was wanting to go ahead and post it to get ideas/suggestions/critiqueing.

How does it look so far. I will next try out the programming side of things.

The schematic is attached in PDF format.

Thanks for all the help.
 

Attachments

Markd77

Joined Sep 7, 2009
2,806
Looks good except MCLR should be pulled high (unless you are using it as an input).
My recomendations:
Segment resistors calculated to give slightly under 20mA.
Base resistors calculated to give around 15mA. (Max collector current is 160mA with all segments lit, base current should be about 1/10th that value).
 
Sounds like your sending out segment data and putting on all 3 cathodes at the same time.
You need to multiplex the display.
1's data to segments and only enables 1's cathode.
Then same for 10's then 100's
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
Thanks for the replies. I made a few changes to the code and just wanted to paste it here. I like keeping all the changes here as I progress so if it can help anyone, it will be posted. Not much has changed in the code. Sorry for not commmenting the code as of yet. I just havent gotten around to it.

Rich (BB code):
#include <htc.h>

int ones = 0b00010000;
int tens = 0b00100000;
int hundreds = 0b01000000;
int zero = 0b00000000;
int one = 0b00000110;
int two = 0b01011011;
int three = 0b01001111;
int four = 0b01100110;
int five = 0b01101101;
int six = 0b01111100;
int seven = 0b00000111;
int eight = 0b01111111;
int nine = 0b01100111;

__CONFIG (INTIO & WDTDIS & MCLRDIS & UNPROTECT);

void pause (unsigned short usvalue);

main ()
{

unsigned char state_led = 0;

ANSEL = 0;
ANSELH = 0;
CM1CON0 = 0;
CM2CON0 = 0;

PORTB = 0x00;
PORTC = 0x00;
TRISB = 0x00;
TRISC = 0x00;

while (1==1)

{
	RB4 = 1;
	RB5 = 0;
	RB6 = 0;	
	state_led++;
	switch (state_led)
		{
			case 1:
				PORTB = ones;
				PORTC = one;
				break;
			case 2:
				PORTB = ones;
				PORTC = two;
				break;
			case 3:
				PORTB = ones;
				PORTC = three;
				break;
			case 4:
				PORTB = ones;
				PORTC = four;
				break;
			case 5:
				PORTB = ones; 
				PORTC = five;
				break;
			case 6:
				PORTB = ones;
				PORTC = six;
				break;
			case 7:
				PORTB = ones;
				PORTC = seven;
				break;
			case 8:
				PORTB = ones;
				PORTC = eight;
				break;
			case 9: 
				PORTB = ones;
				PORTC = nine;
				break;
			default:
				state_led = 0;
				PORTC = zero;
				break;
		}

		pause(1000);


}
}
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
Rich (BB code):
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//This program controls a 3 Digit 8 Segment LED Display (7 Segments and . (dot).  
//The objective of this program is to count from 0 to 999 and then restart at 0.  
//The PIC16F886 Microcontroller from Microchip is being used.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define _LEGACY_HEADERS
#include <htc.h>

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////DEFINE STATEMENTS
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define DelayS(T)		{unsigned char i; for (i = 0; i < T * 10; i++) __delay_ms(100);}	//Delay Macro
#define _XTAL_FREQ				4000000								//Needs to be set for __delay_ms
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////CONFIGURATION FUSES (BITS)
////Master Clear Reset enabled & Internal RC No Clock & Watchdog Timer Disable & Power Up Timer On & Brown Out Reset Disabled &
////Low Voltage Porgramming Disabled & Code Unprotect
__CONFIG (MCLREN & INTIO & WDTDIS & PWRTEN & BORDIS & LVPDIS & UNPROTECT);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

main()
{

void pause (unsigned short usvalue);

ANSEL = 0;											//Initialize A/D Ports off
ANSELH = 0;											//Initialize ........
CM1CON0 = 0;										//Initialize Comparator 1 off
CM2CON0 = 0;										//Initialize Comparator 2 off

//OPTION = 0b01010101;							//OPTION REG
													//xbxxxxx101  1:64
													//xbxxxx0xxx  Prescaler set to Timer0
													//xbxxx1xxxx  (T0SE) set to Increment on high-to-low transition on T0CKI pin
													//xbxx0xxxxx  (T0CS) Internal instruction cycle clock
													//xbx1xxxxxx  (INTEDG) Interrupt on rising edge of INT pin
													//xb0xxxxxxx  (RBPU) PORTB pull-ups are enabled by individual PORT latch values
//RBPU = 0;											//Don't think I need this, but to be safe...PORTB Weak Internal Pullups enabled
//WPUB0 = 0;											//COL_1 Weak pullup is individually DISABLED--OUTPUT 
//WPUB1 = 0;											//COL_2 Weak Pullup is inidivdually DISABLED--OUTPUT
//WPUB2 = 0;											//Not being used...Weak Pullup is individually DISABLED
//WPUB3 = 1;											//ROW_1 Weak Pullup is individually ENABLED--INPUT
//WPUB4 = 1;											//ROW_2 Weak Pullup is individually ENABLED--INPUT
//WPUB5 = 1; 											//ROW_3 Weak Pullup is individually ENABLED--INPUT
//WPUB6 = 1;											//ROW_4 Weak Pullup is individually ENABLED--INPUT
//WPUB7 = 0;											//COL_3 Weak Pullup is individually DISABLED--INPUT

PORTA = 0x00;										//PORTA is cleared and set low
													//PORTA:B0 is set to low,low,low,low,low,low,low,low
PORTC = 0x00;										//PORTC is cleared and set low
													//PORTC7:C0 is set to low,low,low,low,low,low,low,low
TRISA = 0x00;										//PORTA is set to outputs
TRISC = 0x00;										//PORTC is set to outputs

int ones = 0b00001000;
int tens = 0b00010000;
int hundreds = 0b00100000;
int zero = 0b00000000;
int one = 0b00000110;
int two = 0b01011011;
int three = 0b01001111;
int four = 0b01100110;
int five = 0b01101101;
int six = 0b01111100;
int seven = 0b00000111;
int eight = 0b01111111;
int nine = 0b01100111;

unsigned char state_led = 0;

while (1==1)

{
	RA3 = 1;
	RA4 = 0;
	RA5 = 0;
		
	state_led++;
	
	switch (state_led)
		{
			case 1:
				PORTA = ones;
				PORTC = one;
				break;
			case 2:
				PORTA = ones;
				PORTC = two;
				break;
			case 3:
				PORTA = ones;
				PORTC = three;
				break;
			case 4:
				PORTA = ones;
				PORTC = four;
				break;
			case 5:
				PORTA = ones; 
				PORTC = five;
				break;
			case 6:
				PORTA = ones;
				PORTC = six;
				break;
			case 7:
				PORTA = ones;
				PORTC = seven;
				break;
			case 8:
				PORTA = ones;
				PORTC = eight;
				break;
			case 9: 
				PORTA = ones;
				PORTC = nine;
				break;
			default:
				state_led = 0;
				PORTC = zero;
				break;
		}

		pause(1000);


}
}
Here is my most recent code. I also got the circuit breadboarded and of course it doesnt work.:):)

If need be I can send a picture of the breadboarded design, but I pretty much followed my schematic.

Can anyone see anything wrong from the code. I have been messing with it for a couple days now, and I just cant seem to get it to work.
 

stahta01

Joined Jun 9, 2011
133
Your master clear circuit is not what I think it should be; I suggest using the 10K as a pull-up instead of a pull-down. And connect the reset switch to ground and MCLR.

See Figure 14-2 for the recommend circuit for MCLR connection. Note: This one did not have an external reset switch.

Does your setup do anything?

Tim S.
 

Thread Starter

beeson76

Joined Apr 19, 2010
211
Thanks stahta01 for the reply. As of right now, its not doing anything, but that is usually common for me on my first try:):)

Ok, I will use a 10k for the MCLR pin. But when you say pull-up instead of a pull-down, what do you mean. Is that how I initialize the Pin. It being "on" instead of "off" if that is the right terminology.

Also the figure you refer to. Where is it located at.

Thanks for the help. I appreciate it.
 

stahta01

Joined Jun 9, 2011
133
Ok, I will use a 10k for the MCLR pin. But when you say pull-up instead of a pull-down, what do you mean.
The datasheet says 1K pull-up resistor; so I would use 1K instead of 10K as your schematic showed; but the main thing is when MCLR is low the chip does nothing but reset itself. Please READ the data-sheet; if you do not want to fail.
Note: Some PICs can turn off the MCLR in software; but this requires the PIC to leave the reset state.
A pull-up resistor is one that connects to an high (in this case 5 volts).
A Pull-down resistor is one that connects to a low (in this case, and almost all cases, ground).

Also the figure you refer to. Where is it located at.
In the PIC datasheet for this chip; I think added the correct link to it.
http://ww1.microchip.com/downloads/en/DeviceDoc/41291D.pdf


Tim S.
 
Last edited:

Thread Starter

beeson76

Joined Apr 19, 2010
211
Thanks stahta01 again. Sorry about the Diagram 14.1. I found out you meant in the Datasheet. I see that now.

So I must use the Config1 register. I guess I use is something like this:

CONFIG1 0b0000000000000000;

...since its 16 bits wide it looks like. So my resistor should be connected to a high, in my case the 5 volt rail.

Is this correct.

Thanks for the help.
 

stahta01

Joined Jun 9, 2011
133
Thanks stahta01 again. Sorry about the Diagram 14.1. I found out you meant in the Datasheet. I see that now.

So I must use the Config1 register. I guess I use is something like this:

CONFIG1 0b0000000000000000;

...since its 16 bits wide it looks like. So my resistor should be connected to a high, in my case the 5 volt rail.

Is this correct.

Thanks for the help.
I have only a slight idea what this post meant. So, I say it is not correct.

I never set the CONFIG1 value directly.
I always use the __CONFIG Macro.

MCLR with an line above it means it is active low; This means a low input results in resetting the MCU. When in reset mode most MCUs do not do anything that is visible to users outside the chip.
You MUST allow MCLR to raise up to a high value for the MCU to function. The datasheet implies it will work with no connection (it has an internal pull-up resistor, but if your pull-down resistor was too strong(pulled enough current) it would win; but, the preferred circuit is a 1K pull-up with cap connect to ground.

The size of CONFIG1 has nothing to do with needing a high value on MCLR.

Tim S.
 
Last edited:

Thread Starter

beeson76

Joined Apr 19, 2010
211
Ok. I use the __CONFIG bit too. And I have it set (for my MCLR) as:

__CONFIG (MCLREN & ......

So it is enabled in my configuration. So from what I understand I shouldnt include it in my configuration. Or should I include it?
 

stahta01

Joined Jun 9, 2011
133
Ok. I use the __CONFIG bit too. And I have it set (for my MCLR) as:

__CONFIG (MCLREN & ......

So it is enabled in my configuration. So from what I understand I shouldnt include it in my configuration. Or should I include it?
I am not sure but, this site says
http://www.micro-examples.com/public/microex-navig/doc/205-faqs.html
Check your MASTER CLEAR enable bit :
  • If set, the /MCLR pin must be connected to a reset circuit or tied to the Vcc.
  • If not set, /MCLR is an INPUT pin.
Note: Your chip data-sheet says use a resistor to high instead of tying it to high. Also says your MCLR has an internal pull-up so pulling it high with a resistor is likely not needed (From Table 1-1 on page 17 of data-sheet).

Note: You need to read data-sheet page 206 note 4; it applies when internal OSC is used and MCLR is low.
When MCLR is asserted in INTOSC or RC mode, the internal clock oscillator is disabled.
This might keep your circuit from working.
I suggest YOU DO NOT try to use internal OSC and MCLR as input till you run out of all other inputs.
It was not clear to me if when MCLR is disabled what would happen from the datasheet; I would guess the input being low would not disable the Internal Osc; but, I am not sure.


NOTE: I have never used this chip before; all my info is from reading the data-sheet today.

Tim S.
 
Last edited:
Top