LED Display Driver for use with PIC?

Hello.

My current project uses a PIC16F873A to output to an already multiplexed LED Display (Fairchild MSQ6441, 4 digit, 7-segment numeric display).

I would like to relieve some work from the PIC, so I've been looking into LED Display Drivers to pick up the slack. I came across the MAX7221, a nice chip from Maxim... common cathode LED Display Driver that does the multiplexing for you, SPI compatible..easy to use. It supports all 8 digits, so I don't need the extra pins.

Now, Ideally I would like a LED Display Driver that is I2C (not SPI) compatible and drives up to 4 digits. I came across the MAX6958, it looked perfect.. I2C compatible, drives 4 digits, 16 pin PDIP. BUT, you cannot hook up a multiplexed LED Dispaly to it because of it's special multiplexing method (Charlieplexing). You have to connect individual digits to the chip...the chip needs access to each segment (a,b,c,d,e,f) of each digit. I would really like to stick with already multiplexed LED Displays (ie, common cathodes and all segments tied to each other). Anyone know of such a chip that could hook up multiplexed display which is I2C compatible. Thanks for any input.

Reply to
jut.shanahan
Loading thread data ...

What's the problem with getting the PIC to do it?

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

try

formatting link

Reply to
Jim Granville

There shouldn't be that much work to offload. A timer that interrupts about every 4ms, 4 8-bit registers and a 4-bit shift register (or 2-bit counter) are all that's needed. If the processor is running at 4MHz, 10 instructions to do the switch would be 10us. 10us out of 4ms is a mere 0.25%. Even if my estimate if off by 2 or 3X, It's still less than 1% of the CPU cycles.

Noel

Reply to
Noel Henson

I agree with you Noel, probably not even 10 instructions needed. A lot more effort would be needed to run an I2C link.

Reply to
CBarn24050

More than 10, counting save/restore context. But the order of magnitude is correct.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

OK. Let's see how small we can make it. Perhaps it would make a good reference for others.

I do love to make pins and ports do more than one thing so, let's consider

4 8-segment displays (7 plus a .) and 4 push-button switches for input. We'll only need 13 signals.

Let's assume these variables:

DIGIT3 the bit pattern for the left-most digit DIGIT2 the bit pattern for the left-center digit DIGIT1 the bit pattern for the left-center digit DIGIT0 the bit pattern for the right-most digit SELECT the shifter or counter

Who wants to take the first stab at it?

Noel

Reply to
Noel Henson

I was assuming that you were allready in the timer interrupt routine. Less than

10 meant the number of instructions used each time round the loop and not the total number of code instructions. I can't be bothered to actually write the code so I can't actually disagree with you.
Reply to
CBarn24050

Hamilton,

What took you so long? ;) What is the schematic? We'll need to know which PIC pins do what.

Noel

PS: Nice work. Even an RS232 interface.

Reply to
Noel Henson

I see that we need the code to support these functions:

Initialize the timer Enable the interrupt Acknowledge the interrupt Context save Context restore Index into the data storage array Write the output Scan the keys

Did I miss anything?

Noel

Reply to
Noel Henson

"Write the output" is typically composed of- fetch the new segment pattern, turn the old digit drive off, output the new segment pattern, turn the next digit drive on.

You also have to increment the index modulo the number of digits.

For "scan the keys", I'd put debouncing right in the ISR and also stuff any changes into a circular event queue, but that's just me.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

I did something similar recently for the pic16c870, 5 digits +6 buttons on 1 port with a 573 latch. The code wasn't written for smallest size just quick through the interrupt loop. Digit selection 14 instructions, digit drive and button read 6 instructions + a call to a 6 instruction macro + a call to a lookup table (bcd to 7 seg). Button debounce 6 instructions. Worst case time 28 instructions, best case time 22 instructions.

Reply to
CBarn24050

'Write the output' could use a shift register so selecting the proper digit could be as easy as a shift but that would mean that other port bits could be affected in a destructive way; eg. rol PORTB. That would work in instances in which the other PORTB bits are inputs.

Debouncing may or may not be necessary, depending upon the application. If one is needed, there is always the 'tried-and-true' counting approach. For an embedded application, I'd used flags instead of queues. They're much smaller.

Cheers,

Noel

Reply to
Noel Henson

As mentioned before, "the order of magnitude is correct." Nice work. But if we were starting anew, how small could it be made?

Noel

Reply to
Noel Henson

Thanks, I did this last year for a solar controller project. I need to locate the schematic, but I used port D for the segment drivers and port B ( 4 bits ) for the digit drivers.

The interrupt was written in C. I fill a 4 byte array with the display values and set a flag. When the interrupt transfers all four bytes ( three digits and 4 LEDs ) to the display, I check the flag and update the display registers. ( another 4 byte array )

The interrupts run at 1 Milli-second.

I turn off the digit drivers to blank the display, reload port D from the next location in the output array, then turn on the next digit driver.

I also check the switches for any low bits, de-bounce the same bits and pass the key_value back to the main program.

The interrupt runs at about 25 uSec for all of this. ( TEST_PNT is used as a timeing bit. )

25 uSec out of every 1000 uSec = 2.5 % overhead. I also flash the digits without flashing the LEDs.

I am sure it would be smaller code and faster ( less overhead ) but I wrote it over a weekend in C.

// 1 mSec interrupts // run multiplex display

void interrupt timer_0( void ) { TMR0 = -125; T0IF = 0; PORTB = 0x27; // turn off all digits TEST_PNT = 1;

// running .1 sec timer if( !flash_cnt--) { flash_cnt = 100; tenth_sec_cntr++; if( !hund_count--) { hund_count =hund_count_input;

if( flash_state_on ) flash_state_on=0; else flash_state_on=1; } } // display next digit if( mux_cntr == 0 ) { PORTD = DIGITS[ dsply_digit[0] ]; on_digit = ~0x01; // turn on hunds digit //digit_100 = 0; } else if( mux_cntr == 1 ) { PORTD = DIGITS[ dsply_digit[1] ]; on_digit = ~0x02; // turn on tens digit //digit_10 = 0;

} else if( mux_cntr == 2 ) { PORTD = DIGITS[ dsply_digit[2] ]; on_digit = ~0x04; // turn on units digit //digit_1 = 0;

} else if( mux_cntr == 3 ) { PORTD = dsply_digit[3]; on_digit = ~0x20; // turn on LEDs //digit_led = 0;

if( dsply_flag ) { dsply_digit[0] = update_dsply[0]; dsply_digit[1] = update_dsply[1]; dsply_digit[2] = update_dsply[2]; dsply_digit[3] = update_dsply[3];

dsply_flag = 0; } }

// check if blanking if( flash_state_on || cntr==3 ) PORTB = on_digit; // turn ON LED drive

// shift too next digit mux_cntr++; mux_cntr &= 0x03; TEST_PNT = 0;

// check buttons on ports RE0, RE1, RE2, AN3, AN4

}
Reply to
hamilton

I cant remeber the original spec now but lets say 4 digits with 4 buttons, buttons driven via a diode from the multiplex output feeding back to a single port pin. Digits and multiplex pattern alternated in the top 8 registers of a PIC 16c870. Button information returned in the msb of the multiplex register (only need the lower 4 bits for multiplexing). FSR reg dedicated to this thread (could be shared with care by other threads). Code in ISR something like

movlw B'11111000' iorwf fsr,f movf 0,w movwf segment_port incf fsr,f movf 0,w movwf multiplex_port bcf 0,7 btfsc multiplex_port,7 ;(button input line) bsf 0,7 incf fsr,f

Now I,ve written it I'll leave you to test and debug it. mo

Reply to
CBarn24050

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.