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