Greetings. I'm having a problem that reaches beyond my basic knowledge of digital logic and electronics, and so I'm hoping an expert eye can spot the mistake. (Also, please suggest a more appropriate group if I'm in the wrong place.)
I'm working on a seemingly straightforward means of expanding the limited outputs of a PIC 16F88 to 32 pins by way of four 74ABT574 octal D-type flip-flops and a 2-to-4 decoder. The way the trivial design is supposed to work is that each RBn pin of the PIC is attached to a corresponding Dn pin on each of the four 574s. The program would assign their data round-robin style, assigning one word to PORTB and then clocking the destination DFFs using the demuxer. The outputs in this experiment are LEDs run via 1K resistors (3 or 4mA).
I've had some problems, though, and they're somewhat spurious. Sometimes, the outputs of the first 574 always echo PORTB; other times, one or more of the 574s read correctly except for a split second of flicker, which I'm guessing is a momentary read intended for another output, but I have no idea why.
I've simplified the circuit to the minimum that should implement the functionality, done away with the demuxer and three of the four 574s, and the problem remains.
Here is the circuit:
16F88 74ABT574---------- --------------- | Vdd|--> +5V |---+--| GND | RB1|--------------|3 D1 Q1 18|--/\\/\\--|>|---+ | RB2|--------------|4 D2 Q2 17|--/\\/\\--|>|---+ | RB3|--------------|5 D3 Q3 16|--/\\/\\--|>|---+ | RB4|--------------|6 D4 Q4 15|--/\\/\\--|>|---+ | RB5|--------------|7 D5 Q5 14|--/\\/\\--|>|---+ | RB6|--------------|8 D6 Q6 13|--/\\/\\--|>|---+ | RB7|--------------|9 D7 Q7 12|--/\\/\\--|>|---+ | | | | | RA4|--------------|11 CLK | | RA5| --------------- | RA6| | RA7|
----------
The same behavior is exhibited when the LEDs are reversed with cathode on the output and anode on +5V. In theory, I should also be able to switch the CLK of the 574 among RA4-RA7 to output any of the four different output patterns, which would be functionally identical to the full circuit. This does work, insofar as doing this echoes what each of the 574s would have been doing before, but is subject to the same glitches.
I've tried adjusting the delays on the clocks (which shouldn't be necessary; the 74ABT574 specifies a much higher clock frequency than I'm using), not just with the nops in the version at the end of this message but also plugging in an entire delay loop, and the problem remains. I find myself wishing I had an oscilloscope!
The program follows. Is there anything in the program--or, more likely, the circuit itself--that I need to try adjusting?
Thanks a zillion PSM
The program:
errorlevel -302 include "hgt_16f88.inc"
processor 16f88
org 0 goto Start
org 4 ISR retfie
Start
BUF0 equ 0x30 ; - 0x33 ADDRESSBUFFER equ 0x40
Setup bsf STATUS,5 ; set bank 1 movlw b'00000000' movwf TRISA movlw b'00000000' movwf TRISB bcf STATUS,5 ; set bank 0
clrf PORTA
clrf BUF0 clrf BUF0+1 clrf BUF0+2 clrf BUF0+3
Loop ; The first two count forward and backward, respectively incf BUF0,f decf BUF0+1,f
; The third rolls one direction rlf BUF0+2,f btfsc STATUS,C bsf BUF0+2,0
; The fourth rolls the other rrf BUF0+3,f btfsc STATUS,C bsf BUF0+3,7
call SetExternalRegisters call Delay
goto Loop
Delay COUNTH equ 0x20 COUNTL equ 0x21 movlw 0x00 movwf COUNTH movlw 0xDA movwf COUNTL
Delay_Loop ; 16-bit decrement ; 9 instructions per loop ; Time taken = 9 * 4 / osc speed ; For 31.25kHz, 868 = about 1s. decf COUNTL,f incfsz COUNTL,w incf COUNTH,f decf COUNTH,f movf COUNTL,w iorwf COUNTH,w btfss STATUS,Z goto Delay_Loop return
SetExternalRegisters ; Manual version! movf BUF0,w movwf PORTB nop nop nop nop bsf PORTA,4 nop nop nop nop nop nop nop nop bcf PORTA,4 nop nop nop nop nop nop nop nop
movf BUF0+1,w movwf PORTB nop nop nop nop bsf PORTA,5 nop nop nop nop nop nop nop nop bcf PORTA,5 nop nop nop nop nop nop nop nop
movf BUF0+2,w movwf PORTB nop nop nop nop bsf PORTA,6 nop nop nop nop nop nop nop nop bcf PORTA,6 nop nop nop nop nop nop nop nop
movf BUF0+3,w movwf PORTB nop nop nop nop bsf PORTA,7 nop nop nop nop nop nop nop nop bcf PORTA,7 nop nop nop nop nop nop nop nop
; Show a pattern that means "this isn't right" movlw b'11000011' movwf PORTB return
org 0x2007 CONFIG1 ; Use internal oscillator at 31.25kHz dw 0x3f10 end