Moved pins away from the RB1 - RB3 (AN8 - AN10).
Added GOSUB you found.
Modified A/D channel selection.
Sure wish I had one of these chips. BTW, will you be using a different chip?
Code:
'****************************************************************
'* Name : Shift4021.pbp *
'* Author : Darrel Taylor *
'* Date : 9/9/2008 *
'* Version : 1.1 *
'* Notes : Target = 16F883, Internal 8mhz OSC *
'* Thread : Slave PIC to be used like CD4021 chip *
'* http://www.picbasic.co.uk/forum/showthread.php?t=9544 *
'****************************************************************
@ __config _CONFIG1, _INTOSCIO & _WDT_OFF & _LVP_OFF & _CPD_OFF
DEFINE OSC 8
Clear
PloadPin VAR PORTB.0 ; Parallel Load (INT)
ClkPin VAR PORTB.4 ; Serial Clock
SerInPin VAR PORTB.5 ; Serial Input Pin
SerOutPin VAR PORTB.6 ; Serial Output Pin
ADbuff VAR BYTE[8] ; Buffers the A/D readings
ShiftReg VAR BYTE[8] ; The 64-bit shift register
I VAR BYTE ; Index variables
X VAR BYTE
BitIdx VAR BYTE
ADidx VAR BYTE
ADchannel VAR BYTE ; Actual AD ch being used (5,6,7 missing)
ClkState VAR BIT ; for locating clk edges
DataBit VAR BIT ; Serial In read on falling edge
INTE VAR INTCON.4 ; Aliases
INTF VAR INTCON.1
GoDone VAR ADCON0.1
;---------------------------------------------------------------------------
Initialize:
OSCCON = %01110001 ; Internal 8Mhz OSC
INPUT PloadPin ; Input(default), just to make sure
INPUT ClkPin
INPUT SerInPin
LOW SerOutPin ; start with output LOW
ADCON0 = %10000001 ; FOSC/32, CH0, ADON
ANSELH = %00000111 ; Turn off upper A/D ports (8,9,10 used)
INTF = 0 ; clear INT flag
INTE = 1 ; enable INT interrupt
ON INTERRUPT goto ParallelLoad
;---------------------------------------------------------------------------
Main:
if !GoDone then GOSUB NextAD ; conversion complete, get results
IF ClkPin then ; wait for Rising edge
if !ClkState then
ClkState = 1
GOSUB NextBit ; Rising edge found, shift data
endif
else ; wait for falling edge
if ClkState then
ClkState = 0
DataBit = SerInPin ; falling edge found, read input
endif
endif
GOTO Main
; ---- Cycle thru each A/D channel, one at a time --------------------------
NextAD:
ADbuff(ADidx) = ADRESH ; save A/D result
ADidx = ADidx + 1 ; point to next A/D channel
if ADidx = 8 then ADidx = 0 ; circle around
ADchannel = ADidx
if ADidx > 4 then
ADchannel = ADchannel + 3 ; correct for missing AN 5,6,7
endif
ADCON0 = %10000001 | (ADchannel << 2) ; Set the A/D ch.
for I = 1 to 5 ; Acquisition time
@ NOP
NEXT I
GoDone = 1 ; Start A/D conversion
RETURN
DISABLE
; ---- Parallel Load -- copy A/D buffer to Shift register ------------------
ParallelLoad:
For X = 0 to 7 ; Copy A/D results
ShiftReg(X) = ADbuff(X)
NEXT X
SerOutPin = ShiftReg.0(63) ; put MSB on Pin
BitIdx = 63 ; start shifting from MSB
DataBit = SerInPin ; read input bit
INTF = 0 ; clear the interrupt flag
RESUME
; ---- Put next bit on the output pin --------------------------------------
NextBit:
ShiftReg.0(BitIdx) = DataBit ; replace bit with the input data
BitIdx = BitIdx - 1 ; point to next bit
if BitIdx.7 = 1 then BitIdx = 63 ; circle back to beginning
SerOutPin = ShiftReg.0(BitIdx) ; put data on output Pin
return
Bookmarks