Home PIC 12F509 4x4x4 LED Cube with 12F509 & MM5451YN

Main Menu

4x4x4 LED Cube with 12F509 & MM5451YN
thumbI was following this thread at electro-tech-online.com and decided to build a new, bigger LED cube. I'm controlling it with a PIC 12F509 and a Micrel MM5451YN. I'm using the bare-bones 12F509 only because that's what the original poster in the thread was using.

The MM5451YN is a 35-bit shift register with open drain drivers. I use the first 16 bits to control the cathodes of my common-anode cube, and the next 4 bits to control the anodes for each "level". I scraped through the bottom of my transistor bin and found four 2N4403 PNP's to use as high-side switches for multiplexing the levels.


 

 

 

Here's a YouTube movie of the cube in action. Only one pattern for now:

 

 

 

Here I'm testing out the MM5451YN (left). On the right is a pic of my 4x4 LED jig. The holes are drilled on 1" centers. I solder together one level at a time.

LED test Cube Jig

 

A bit closer view of a level being assembled (left). A completed level pulled out of the jig and flipped over (right).

Jig Close Flip

 

Three completed levels, ready to be put together (left). Two levels soldered together (right). 

Two Levels Cube

 

Completed cube (left). Control wiring soldered to cube (right). 

Completed Cube Control Wires

 

Another view of the control lines (left). The breadboard with anode driver transistors upper right (right). 

Control Wires 2 Breadboard

 

Completed hardware blinking LEDs (left). Closeup of the PIC and the two SPDT switches for isolation of the PGD/PGC lines for programming (right).

Blinking Breadboard 2

 

This piece of code has a pattern that lights LEDs in a spiral animation, starting at the bottom and spiraling around the outside to the top. Other animations can be built in the "patt3" table, but you have to be careful not to make them too big or they push the code past the 12F509's "half-page limit" (256 bytes) for subroutine calls, and the program breaks.

 

spiral.asm

	include	"P12F509.INC"
__config _IntRC_OSC & _WDT_OFF & _MCLRE_ON

D equ 0
CP equ 1

cblock 0x07
d1,d2,d3,count,count2,patlen,patrep,temp,anode,offset,fsr1,frames,cathptr
plex,cath1a,cath1b,cath2a,cath2b,cath3a,cath3b,cath4a,cath4b
endc

org 0x000
goto init
patt3 addwf PCL,f
retlw 0x10 ;pattern length - # of frames
retlw 0x0a ;# of reps

retlw 0x88
retlw 0x88
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x11
retlw 0x11
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0xf0
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x88
retlw 0x88
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x11
retlw 0x11
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x88
retlw 0x88
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x11
retlw 0x11
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0x00
retlw 0x00

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x88
retlw 0x88

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x0f

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x11
retlw 0x11

retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0xf0
retlw 0x00

init movlw b'11001000' ;clear T0CS for output on GPIO2
option
movlw b'00001000' ;set pins to all outs
tris GPIO
clrf GPIO ;zero all pins
movlw 0x08 ;set start level
movwf anode
movlw cathptr ;set cathode pointer
movwf cathptr
clrf plex
bcf GPIO,D ;init MM5451
nop
bsf GPIO,CP
nop
bcf GPIO,CP

spiral clrf offset ;point to start of table
movf offset,w ;get pattern length
call patt3
movwf patlen
incf offset,f ;get # of reps
movf offset,w
call patt3
movwf patrep
incf offset,f
spir1 call isr ;multiplex 256 times
decfsz plex,f
goto spir1
anim movlw 0x08 ;set bytes per frame counter - 8 bytes
movwf count
movlw cath1a ;cathode pointer storage
movwf FSR
mloop movf offset,w ;get a byte of new pattern
call patt3
movwf INDF
incf offset,f ;increment pointers
incf FSR,f
decfsz count,f ;frame done?
goto mloop
decfsz patlen,f ;pattern done?
goto spir1
reset movlw 0x02 ;point to start of frames in table
movwf offset
decfsz patrep,f ;# of reps complete?
goto spir2 ;no, fix patlen and go again
goto bail ;yes, done
spir2 movlw 0 ;get patlen again
call patt3
movwf patlen
goto spir1
bail goto spiral

;***************************
;"interrupt" service routine
isr rlf anode,f ;change to next level
movlw 2 ;increment cathode pointer
addwf cathptr,f
movlw 0x10 ;is anode > 0x08?
subwf anode,w
btfss STATUS,Z
goto shift ;no, go ahead
movlw 1 ;yes, reset to anode 1
movwf anode
movlw cath1b ;and reset cathode pointer
movwf cathptr
shift movf cathptr,w ;load FSR
movwf FSR
bsf GPIO,D ;shift out start bit
nop
bsf GPIO,CP
nop
bcf GPIO,CP

movlw 0x02 ;set byte counter
movwf count2
shift5 movlw 0x08 ;set loop counter
movwf count
movf INDF,w ;get a byte
movwf temp
shift1 rrf temp,f ;rotate ms-bit into carry
btfsc STATUS,C ;is it 0?
goto shift2 ;no, shift out a 1
goto shift3 ;yes, shift out a 0
shift2 bsf GPIO,D
nop
bsf GPIO,CP ;blip clock
nop
bcf GPIO,CP
goto shift4
shift3 bcf GPIO,D
nop
bsf GPIO,CP ;blip clock
nop
bcf GPIO,CP
shift4 decfsz count,f ;done 8-bits?
goto shift1 ;no, go again
decfsz count2,f
goto shift6
goto shanode ;done cathodes - go do anode
shift6 decf FSR,f
goto shift5

shanode movlw 0x08 ;shift out anode byte
movwf count
movf anode,w
movwf temp
shan1 rrf temp,f
btfsc STATUS,C
goto shan2
goto shan3
shan2 bsf GPIO,D
nop
bsf GPIO,CP
nop
bcf GPIO,CP
goto shan4
shan3 bcf GPIO,D
nop
bsf GPIO,CP
nop
bcf GPIO,CP
shan4 decfsz count,f
goto shan1

last3 movlw 0x0b ;shift out last 11 bits
movwf count
l3loop bcf GPIO,D
nop
bsf GPIO,CP
nop
bcf GPIO,CP
decfsz count,f
goto l3loop
retlw 0

end