Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Number Breakdown

Status
Not open for further replies.
All
Thanks for all you input with all the info I think that I can make this work
 
Now that I have digits broken down into BCD, how do I push the four bytes to the port for output to the decoder?
 
You need to tell us how and what hardware you have attached. Do you have a schematic?

Mike.
 
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.
 
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.
 
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;
   
    if(!SysOpbits.Advance)
    {
        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: 286
  • Indication.pdf
    136.3 KB · Views: 287
Last edited:
I don't understand a couple of things about your code.
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.
 
Pommie I am advancing Digits on a TMR2 set for a 10 ms interrupt. Dig3 is in tenths for the decimal point.
 
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.
 
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 (!SysOpbits.Advance)
    {
        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.
 
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.
 
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:
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).

HTB1PtQgavfsK1RjSszbq6AqBXXae.jpg
 

Attachments

  • TM1637 Datasheet.pdf
    688.1 KB · Views: 318
Last edited:
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?
 
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:
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.

New Articles From Microcontroller Tips

Back
Top