I came up with this for a chap several years ago. Would something like this work? I would use a newer (and less expensive) device, perhaps an 18 pin 16F1527 ($1.73) or a 20 pin 16F1507 ($1.53)...
Cheerful regards, Mike
Code:
;******************************************************************
; *
; Filename: Forum 4477 IC v1.asm *
; Author: Mike McLaren, K8LH *
; Date: 14-Sep-07 (rev 29-Sep-07) *
; *
; 8-bit Hex to Dual 7-Segment LED Decoder/Driver IC Firmware *
; *
; Uses a 16F628A with a 4-MHz INTOSC and Eric Gibbs standard *
; multiplexed dual-digit common cathode display circuit *
; *
; Digit 1 (left) inputs are RA7..RA4 (msb..lsb) *
; Digit 2 (right) inputs are RA3..RA0 (msb..lsb) *
; Segments A..G connected to RB0..RB6 via 330 ohm resistors *
; Common cathodes connect to RB7 via a 2 transistor circuit *
; *
; MPLab: 7.40 (tabs=8) *
; MPAsm: 5.03 *
; *
;******************************************************************
#include <p16f628a.inc>
errorlevel -302
radix dec
__config _MCLRE_OFF & _LVP_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT
;
; variables
;
digsel equ 0x21 ; digit select bit b7
delayhi equ 0x22 ; DelayCy() subsystem var'
;==================================================================
; K8LH DelayCy() subsystem macro generates four instructions =
;==================================================================
radix dec
clock equ 4 ; 4, 8, 12, 16, 20 (MHz), etc.
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ clock/4*1000 ; cycles/millisecond multiplier
DelayCy macro delay ; 11..327690 cycle range
movlw high((delay-11)/5)+1
movwf delayhi
movlw low ((delay-11)/5)
call uDelay-((delay-11)%5)
endm
;******************************************************************
; Reset vector *
;******************************************************************
org 0x0000
v_reset
clrf STATUS ; force bank 0 |B0
;
; // psuedo C code program example
;
; char segdata [] = { 0b00111111, // "0" -|-|F|E|D|C|B|A
; 0b00000110, // "1" -|-|-|-|-|C|B|-
; 0b01011011, // "2" -|G|-|E|D|-|B|A
; 0b01001111, // "3" -|G|-|-|D|C|B|A
; 0b01100110, // "4" -|G|F|-|-|C|B|-
; 0b01101101, // "5" -|G|F|-|D|C|-|A
; 0b01111101, // "6" -|G|F|E|D|C|-|A
; 0b00000111, // "7" -|-|-|-|-|C|B|A
; 0b01111111, // "8" -|G|F|E|D|C|B|A
; 0b01101111, // "9" -|G|F|-|D|C|B|A
; 0b01110111, // "A" -|G|F|E|-|C|B|A
; 0b01111100, // "b" -|G|F|E|D|C|-|-
; 0b00111001, // "C" -|-|F|E|D|-|-|A
; 0b01011110, // "d" -|G|-|E|D|C|B|-
; 0b01111001, // "E" -|G|F|E|D|-|-|A
; 0b01110001 }; // "F" -|G|F|E|-|-|-|A
;
; void Main()
; { static unsigned char digsel = 0; // digit select, 0 or 128
; cmcon = 7; // turn comparator off
; trisa = 255; // Port A all inputs
; trisb = 0; // Port B all outputs
; while(1) // loop forever
; { unsigned char work = porta; // sample inputs
; if(digsel) // if left (hi) digit
; work /= 16; // use hi nibble, 0..F
; else // otherwise
; work &= 15; // use lo nibble, 0..F
; work = segdata[work]; // get segment data
; work |= digsel; // pick up digit select bit
; portb = work; // update display
; DelayMS(8); // ~60 Hz refresh rate
; digsel ^= 128; // toggle digit select bit
; } //
; } //
;
movlw h'07' ; turn comparator off |B0
movwf CMCON ; for digital I/O |B0
;
; setup ports and display sub-system variables
;
bsf STATUS,RP0 ; bank 1 |B1
movlw h'FF' ; |B1
movwf TRISA ; make Port A all inputs |B1
clrf TRISB ; make Port B all outputs |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf digsel ; init b7 digit select bit |B0
;
; isochronous loop (8-mS, 50% duty cycle, 62.5 Hz refresh rate)
;
Display
swapf PORTA,W ; W = hi nybble in b3..b0 bits |B0
btfss digsel,7 ; left digit? yes, skip, else |B0
movf PORTA,W ; W = lo nybble in b3..b0 bits |B0
andlw b'00001111' ; mask off upper 4 bits |B0
call SegData ; get segment data in W |B0
iorwf digsel,W ; add digit select bit in b7 |B0
movwf PORTB ; display new digit |B0
DelayCy(8*msecs-16) ; 8-msecs minus 16 cycles |B0
movlw b'10000000' ; mask for digit select bit |B0
xorwf digsel,F ; toggle b7 digit select bit |B0
goto Display ; loop forever |B0
;******************************************************************
; Subroutines *
;******************************************************************
SegData
addwf PCL,F ; |B0
retlw b'00111111' ; "0" -|-|F|E|D|C|B|A
retlw b'00000110' ; "1" -|-|-|-|-|C|B|-
retlw b'01011011' ; "2" -|G|-|E|D|-|B|A
retlw b'01001111' ; "3" -|G|-|-|D|C|B|A
retlw b'01100110' ; "4" -|G|F|-|-|C|B|-
retlw b'01101101' ; "5" -|G|F|-|D|C|-|A
retlw b'01111101' ; "6" -|G|F|E|D|C|-|A
retlw b'00000111' ; "7" -|-|-|-|-|C|B|A
retlw b'01111111' ; "8" -|G|F|E|D|C|B|A
retlw b'01101111' ; "9" -|G|F|-|D|C|B|A
retlw b'01110111' ; "A" -|G|F|E|-|C|B|A
retlw b'01111100' ; "b" -|G|F|E|D|C|-|-
retlw b'00111001' ; "C" -|-|F|E|D|-|-|A
retlw b'01011110' ; "d" -|G|-|E|D|C|B|-
retlw b'01111001' ; "E" -|G|F|E|D|-|-|A
retlw b'01110001' ; "F" -|G|F|E|-|-|-|A
;******************************************************************
; K8LH DelayCy() subsystem 16-bit uDelay subroutine *
;******************************************************************
nop ; entry for (delay-11)%5 == 4 |B0
nop ; entry for (delay-11)%5 == 3 |B0
nop ; entry for (delay-11)%5 == 2 |B0
nop ; entry for (delay-11)%5 == 1 |B0
uDelay addlw -1 ; subtract 5 cycle loop time |B0
skpc ; borrow? no, skip, else |B0
decfsz delayhi,F ; done? yes, skip, else |B0
goto uDelay ; do another loop |B0
return ; |B0
;******************************************************************
end