futz
Active Member
Here is where my electronics noobishness comes in.Yes, you could drive the anodes via high side PNPs. So 4*4 is 16 cathodes plus 4 anodes can fit on two 12 bit shift registers.
Last edited:
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Here is where my electronics noobishness comes in.Yes, you could drive the anodes via high side PNPs. So 4*4 is 16 cathodes plus 4 anodes can fit on two 12 bit shift registers.
I understand (kinda) how to do a high side PNP switch, but what transistor can switch 320mA (16 LEDs @ 20mA)?
Here is where my electronics noobishness comes in.I understand (kinda) how to do a high side PNP switch, but what transistor can switch 320mA (16 LEDs @ 20mA)? Or should I be looking at MOSFET's or maybe Darlington arrays?
Yes, but only as a bit of a challenge. When I get sick of the 12F509, out it goes and I'll control it with something that has interrupts and a bit more memory, and that I can program in C.Looks good, are you still using the 509?
I had my 12F509 4x4x4 cube code working nicely - multiplexer/display handler/pattern sequencer all working fine. Then I added another pattern (pushing some of my subroutines beyond the half page limit) and found out what you guys were talking about! Oh boy! What a mess!Total memory space 1024 words, 512 word pages, so need to set page select bit (PA0) in STATUS register to access all of memory.
I had my 12F509 4x4x4 cube code working nicely - multiplexer/display handler/pattern sequencer all working fine. Then I added another pattern (pushing some of my subroutines beyond the half page limit) and found out what you guys were talking about! Oh boy! What a mess! I'm just now tinkering with setting/clearing PA0 bits all thru the code to see if I can get it to all work. Sure makes what should be a simple thing into a royal pain in the butt!
I think I hate the 12F509. What were they thinking? A timer with no interrupt! Paged program memory. Bleh. Soon I'll get disgusted enough to switch to the 12F683.
Why not to move straight to the 18F family? Easier to program and more powerful.
You've obviously not read the entire thread.Why not to move straight to the 18F family? Easier to program and more powerful.
I originally picked the 12F509 only because the original poster, Darkstar64, was using it to do a 3x3x3 cube. I first said that it would be difficult (it wasn't, tho the 509's lack of interrupts didn't help any in that regard) and then decided to do a 4x4x4 with it anyway. I'd been wanting to do one for a while anyway. It's much better than the 3x3x3 I did previously.Yes, but only as a bit of a challenge. When I get sick of the 12F509, out it goes and I'll control it with something that has interrupts and a bit more memory, and that I can program in C.Pommie said:Looks good, are you still using the 509?
See below. It's not terribly impressive, but it works.futz do you mind posting the assembler for what you have. Maybe I can adapt it for my needs?
And you're testing with nothing else except the VPP, PGD and PGC lines connected to the pins? VPP to MCLR (GP3), PGD to GP0, PGC to GP1. The programmer's VDD and Ground must be connected to your target circuit. You need a 10K-33K pullup on the MCLR pin.Also I still can't get ISCP working. It might be the hookup. I'm going to test it once again with a ohmmeter to make sure its a good connection
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
patt1 addwf PCL,f
retlw 0x04 ;pattern length - # of frames
retlw 0x0a ;# of reps
retlw 0xf0
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0x11
retlw 0x11
retlw 0x11
retlw 0x11
retlw 0x11
retlw 0x11
retlw 0x11
retlw 0x11
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x0f
retlw 0x88
retlw 0x88
retlw 0x88
retlw 0x88
retlw 0x88
retlw 0x88
retlw 0x88
retlw 0x88
patt2 addwf PCL,f
retlw 0x04 ;pattern length - # of frames
retlw 0x0a ;# of reps
retlw 0xf0
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0xf0
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0xff
retlw 0xff
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x0f
retlw 0x00
retlw 0x0f
retlw 0xff
retlw 0xff
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
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
main call horiz
call vert
goto main
horiz clrf offset ;point to start of table
movf offset,w ;get pattern length
call patt1
movwf patlen
incf offset,f ;get # of reps
movf offset,w
call patt1
movwf patrep
incf offset,f
horiz1 call isr ;multiplex 256 times
decfsz plex,f
goto horiz1
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 patt1
movwf INDF
incf offset,f ;increment pointers
incf FSR,f
decfsz count,f ;frame done?
goto mloop
decfsz patlen,f ;pattern done?
goto horiz1
reset movlw 0x02 ;point to start of frames in table
movwf offset
decfsz patrep,f ;# of reps complete?
goto horiz2 ;no, fix patlen and go again
goto bail ;yes, done
horiz2 movlw 0 ;get patlen again
call patt1
movwf patlen
goto horiz1
bail retlw 0
vert clrf offset ;point to start of table
movf offset,w ;get pattern length
call patt2
movwf patlen
incf offset,f ;get # of reps
movf offset,w
call patt2
movwf patrep
incf offset,f
vert1 call isr ;multiplex 256 times
decfsz plex,f
goto vert1
vtanim movlw 0x08 ;set bytes per frame counter - 8 bytes
movwf count
movlw cath1a ;cathode pointer storage
movwf FSR
vtloop movf offset,w ;get a byte of new pattern
call patt2
movwf INDF
incf offset,f ;increment pointers
incf FSR,f
decfsz count,f ;frame done?
goto vtloop
decfsz patlen,f ;pattern done?
goto vert1
vtrst movlw 0x02 ;point to start of frames in table
movwf offset
decfsz patrep,f ;# of reps complete?
goto vert2 ;no, fix patlen and go again
goto vtbail ;yes, done
vert2 movlw 0 ;get patlen again
call patt2
movwf patlen
goto vert1
vtbail retlw 0
;***************************
;"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
list p=12F509 ; list directive to define processor
#include <p12F509.inc> ; processor specific variable definitions
__CONFIG _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
cblock 0x07
;***** VARIABLE DEFINITIONS
count,temp
D
CP
delay
endc
;**********************************************************************
RESET_VECTOR CODE 0x3FF ; processor reset vector
; Internal RC calibration value is placed at location 0x3FF by Microchip
; as a movlw k, where the k is a literal value.
MAIN CODE 0x000
movwf OSCCAL ; update register with factory cal value
movlw b'00001000' ;set pins to all outs
tris GPIO
start
movlw b'01010101'
movwf temp
movlw b'11100101'
movwf temp
goto start
;********Subroutines********
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,1
nop
bsf GPIO,1 ;blip clock
nop
bcf GPIO,1
goto shift4
shift3 bcf GPIO,1
nop
bsf GPIO,1 ;blip clock
nop
bcf GPIO,1
shift4 decfsz count,f ;done 8-bits?
goto shift1 ;no, go again
END ; End of program !!