Continue to Site

# Number Breakdown

Status
Not open for further replies.

#### TucsonDon

##### Member
All
Thanks for all you input with all the info I think that I can make this work

#### TucsonDon

##### Member
Now that I have digits broken down into BCD, how do I push the four bytes to the port for output to the decoder?

#### Pommie

##### Well-Known Member
You need to tell us how and what hardware you have attached. Do you have a schematic?

Mike.

#### TucsonDon

##### Member
Pommie I am using a PIC16F1788. I have PortB 3:0 configured for the BCD input to the decoder (SN74LS47) and PortB 7:4 as the individual digits on a 4digit-7segment display.

What I came up with is:

C:
uint8_t BCD;
LATBbits.LATB = (BCD & 0xFF)

Not sure if this is the most efficient way to do it but seam to work.

#### Pommie

##### Well-Known Member
You need to display each digit for a short period, say 10mS and then switch to the next digit. I'm assuming you're using common anode displays as the 47 needs them.

Without interrupts, you could do,
Code:
while(1){
LATB=0;                            //ensure all off
LATB=digit1+0x80;        //turn on digit 1
delay_ms(10);
LATB=0;                            //ensure all off
LATB=digit2+0x40;        //turn on digit 2
delay_ms(10);
LATB=0;                            //ensure all off
LATB=digit3+0x20;        //turn on digit 3
delay_ms(10);
LATB=0;                            //ensure all off
LATB=digit4+0x10;        //turn on digit 4
delay_ms(10);
}
However, this would be much better using a 10mS interrupt.

Mike.
Actually, I've just realized that this will require 4 x 74LS47s - do you have a schematic?
Edit, I guess you have all the cathodes connected together and to 1 x 74LS47 and the individual anodes to portb 4-7 in which case the above should work.

#### TucsonDon

##### Member
C:
static void DisplayTemp(float ConvertDisplay)
{
int display;
uint8_t tenths;
uint8_t ones;
uint8_t tens;
uint8_t hundreds;
uint8_t BCD;
uint8_t value;

ConvertDisplay = ConvertDisplay * 10;
display = (int)ConvertDisplay;

tenths = display%10;
display /= 10;
ones = display%10;
display /= 10;
tens = display%10;
display /= 10;
hundreds = display;

{
switch (Digits)
{
case hundred:

BCD = DecToBCD(hundreds);
Dig1_SetHigh();                                         //RB4
break;

case ten:

BCD = DecToBCD(tens);
Dig2_SetHigh();                                  //RB5
break;

case one:

BCD = DecToBCD(ones);
Dig3_SetHigh();                                   //RB6
break;

case tenth:

BCD = DecToBCD(tenths);
Dig3_SetHigh();                                    //RB6 for decimal point
Dig4_SetHigh();                                 //RB7
DP_SetLow();                             //decimal point on
break;
}
}
LATBbits.LATB = (BCD & 0xFF);
}

Pommie I am advancing this every 10ms and triggering each digit.

#### Attachments

• LDQ-M282RI 7Seg.pdf
75.8 KB · Views: 63
• Indication.pdf
136.3 KB · Views: 61
Last edited:

#### Pommie

##### Well-Known Member
You don't appear to be advancing Digits!! Assuming Digits goes from 0 to 3 then changing to switch(++Digits&3) should do it.
Why is Dig3 in both one and tenth code?

Also, to avoid ghosting set LATB=0 before the switch instruction.

Mike.

#### TucsonDon

##### Member
Pommie I am advancing Digits on a TMR2 set for a 10 ms interrupt. Dig3 is in tenths for the decimal point.

#### Pommie

##### Well-Known Member
If you need the digit 3's decimal point set then it needs to be in the one: section.

If you've got a 10mS interrupt then why not do the digits in that?

Mike.

#### TucsonDon

##### Member
If you need the digit 3's decimal point set then it needs to be in the one: section.

Mike.

C:
    switch (Digits)
{
case hundred:

BCD = DecToBCD(hundreds);
Dig1_SetHigh();
break;

case ten:

BCD = DecToBCD(tens);
Dig2_SetHigh();
break;

case one:

BCD = DecToBCD(ones);
Dig3_SetHigh();
DP_SetLow();
break;

case tenth:

BCD = DecToBCD(tenths);
Dig4_SetHigh();
break;
}
LATBbits.LATB |= BCD;

If you've got a 10mS interrupt then why not do the digits in that?

Mike.

C:
void TMR2_ISR(void)
{

// clear the TMR2 interrupt flag
PIR1bits.TMR2IF = 0;

{
if (Digits++ == tenth)
{
Digits = hundred;
}
BCD1_SetLow();
BCD2_SetLow();
BCD4_SetLow();
BCD8_SetLow();
Dig1_SetLow();
Dig2_SetLow();
Dig3_SetLow();
Dig4_SetLow();
DP_SetHigh();
}

if(TMR2_InterruptHandler)
{
TMR2_InterruptHandler();
}
}

I also had to change loading the BCD to the port from an AND to an OR because it was setting the output to the digits low.

#### ChrisP58

##### Well-Known Member
This comment is about the way you're using current limiting resistors for the 7 segment display.

You have placed the resistors in the digit lines instead of the segment lines. This will cause the brightness of the digit to change depending on how many segments are lit in the digit. For example, when a one is displayed, the total current is shared by 2 segments. But when an eight is displayed, that same current is shared by 7 segments. So a one will be brighter than and eight.

It would be better to place the resistors in the segment lines.

#### TucsonDon

##### Member
This comment is about the way you're using current limiting resistors for the 7 segment display.

You have placed the resistors in the digit lines instead of the segment lines. This will cause the brightness of the digit to change depending on how many segments are lit in the digit. For example, when a one is displayed, the total current is shared by 2 segments. But when an eight is displayed, that same current is shared by 7 segments. So a one will be brighter than and eight.

It would be better to place the resistors in the segment lines.

ChrisP58 Thank you for pointing that out. Because the router in my PCB program limits me to 250 pads (current design is 250 pads) I will have to eliminate the lamp test for the other LED's. JTOL

Last edited:

#### Mike - K8LH

##### Well-Known Member
Are you locked into the 74LS47? A display driver chip like the TM1637 will drive up to 6 common anode displays using a 2-pin interface (CLK & DIO) and it handles display refresh. It's available in a DIP-20 or SOP20 package. You can get 5 chips for a couple bucks from AliExpress vendors or 4-digit 0.56" modules for about \$3 (including shipping).

#### Attachments

• TM1637 Datasheet.pdf
688.1 KB · Views: 70
Last edited:

#### Pommie

##### Well-Known Member
I don't understand how this bit of code can work.
Code:
   if(TMR2_InterruptHandler)
{
TMR2_InterruptHandler();
}

Mike.
Mike - K8LH , I like those displays, played with some max7219 driven displays but 8 digits is normally too much. Four is perfect.
Edit, I note they have both the DP and the colon LEDs - are these all controllable?

#### nsaspook

##### Well-Known Member
I don't understand how this bit of code can work.
Code:
   if(TMR2_InterruptHandler)
{
TMR2_InterruptHandler();
}
It checks for a 'NULL' function pointer as a sanity check before executing the function pointer.

TMR2_InterruptHandler is a function pointer that's declared somewhere.

A routine to load the function pointer with a 'valid' function address.
C:
void (*TMR2_InterruptHandler)(void);

void TMR2_SetInterruptHandler(void (* InterruptHandler)(void)){
TMR2_InterruptHandler = InterruptHandler;
}

Last edited:

#### TucsonDon

##### Member
I don't understand how this bit of code can work.
Code:
   if(TMR2_InterruptHandler)
{
TMR2_InterruptHandler();
}

Mike.
Mike - K8LH , I like those displays, played with some max7219 driven displays but 8 digits is normally too much. Four is perfect.
Edit, I note they have both the DP and the colon LEDs - are these all controllable?

That is from Microchip Code Configurator in MPLab.

Status
Not open for further replies.

Replies
6
Views
1K
Replies
0
Views
3K
Replies
1
Views
6K
Replies
9
Views
2K
Replies
6
Views
1K