Searching \ for 'Fr. Tom's Shift Register Tutorial' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=toms+shift+register
Search entire site for: 'Fr. Tom's Shift Register Tutorial'.

Truncated match.
PICList Thread
'Fr. Tom's Shift Register Tutorial'
1998\06\18@142802 by Thomas McGahee

flavicon
face
Stewart,
I do not use Basic Stamps at all, but I do use shift registers with PICs.
The info I will give is pretty much applicable to any kind of microcontroller,
and I have even used the techniques with IBM PC parallel ports when
necessary. You should be able to apply the info given to a Basic Stamp
without much trouble, but for the sake of helping the most PIC list
members as possible, I will speak in terms of the PIC, not the Basic Stamp.

This posting will contain just the info concerning multi-bit INPUT to
a PIC using serial techniques. If enough members find this useful, then I
might prepare a similar tutorial on multi-bit OUTPUT from a PIC using serial
techniques. No sense in my wasting my time if no one is interested in this
stuff.

*****
PARALLEL TO SERIAL INPUT TO A PIC USING A 74165
(Basic info will also apply to several other chips)
Written by Fr. Tom McGahee  tom_mcgahee@sigmais,com  copyright 1998
As a courtesy to the author, please include the above info if you share this
information with others. Permission granted for personal use.

If you find any errors, or have any additions to be made to the text, or
have any comments to make about this tutorial, please notify me by e-mail:
spam_OUTtom_mcgaheeTakeThisOuTspamsigmais.com

INPUT:
To get data INTO a PIC you can use a 74165 type parallel to serial chip.
These chips have:
       8 parallel input lines
       A serial input line that allows you to cascade multiple chips
       A Clock and /Clock Inhibit
       An asynchronous Shift /Load control
       Both a normal and inverted serial output (Q and /Q)

Let's look at how each of these is used:
All lines are TTL level and will interface directly to the PIC.

*       8 parallel input lines
These receive the parallel data from the 'outside' world. This can be
from switches, transistors, TTL or CMOS devices, etc. Note that more than
one 74165 can be cascaded, so that any number of parallel input lines
get funneled into a single bit input port.

*       The serial input line that allows you to cascade multiple chips.
You only use this if you are connecting multiple 74165 chips together. If this
is
the case, then the Q output of the preceding stage connects to this line. If
you do not wish to use it, then tie it either to ground or +5.

Hint: When cascading 74165 chips together, connect the Clock1 to Clock2,
/Clock Inhibit1 to /Clock Inhibit2, and Shift /Load Control1 to
Shift /Load Control2. That way the PIC will control both in synchronization.
You can cascade as many 74165s as you want.

Sneaky Trick (1): You can use the serial input as a 9th input so long as you
keep
the following in mind: All other inputs are latched when the /Load signal is
pulsed low, but NOT *this* 'input'. It is effectively 'captured' as soon as you
perform the first shift using the clock, however.

*       The Clock and /Clock Inhibit
Tie the Clock Inhibit LOW to disable the inhibit permanently. The rising edge
of the Clock will cause the latched data present in the shift register to
be shifted.

Gotchas: Note that the rightmost bit of parallel data should be read in
BEFORE doing any shifting with the clock! Once you perform a shift, the data
moves to the right, and the rightmost digit is LOST. In other words, always
perform a Read *before* Shifting.

Sneaky Trick (2A): The Clock and the /Clock Inhibit lines are inter-changeable.
When laying out a PC board, you may swap pins 1 and 2. Also, you can just
tie Clock and /Clock Inhibit together and treat them simply as a combined
Clock. This does increase the TTL loading, but it is not a problem.

Sneaky Trick (2B): You can often SHARE this output with other devices.
If you are not running the input routine via an interrupt, then you
can safely share this output. You can get away with this, because you
will generally do a /Load just prior to assembling the data from
the serial port. So, if some other routine has previously used this
output, *who cares*? You *DO* have to make sure that the sharing is OK
from the other device's point of view, of course. Some outputs are sort of
like 'set up' bits, such as the R/W line on an LCD display. You can
flip 'em around all you want, as long as they are set up properly
JUST PRIOR to actually issuing a device command. Sharing a single
output line in such a case makes a lot of sense, but it is not immediately
evident to some people that this is allowable.

*       The asynchronous Shift /Load control
This line is normally held high. You pulse it low when you want to latch the
current state of the inputs. While this line is low, clocking is
automatically inhibited.

Sneaky Trick (3A): If you have the Shift /Load Control held low (/Load), then
the Q output will follow the state of the rightmost parallel input.
This allows you to monitor this particular line in real-time. No shifting
required to read it, and if attached to an input that allows interrupt
on change, then you can use this trick to cause the interrupt routine
to automatically be triggered by a pulse on the last parallel input. The
interrupt routine can then shift in the rest of the data. Note that if
you combine this trick with the sneaky trick (1), then you can get a full
8 'static' data bits and one 'dynamic' data bit that can initiate an
interrupt.

Sneaky Trick (3B): You can often SHARE this output with other devices.
If you are not running the input routine via an interrupt, then you
can safely share this output. You can get away with this, because you
will generally do a /Load just prior to assembling the data from
the serial port. You may have problems if you try to combine sneaky
tricks (3A) and (3B). So, if some other routine has previously used this
output, *who cares*? You *DO* have to make sure that the sharing is OK
from the other device's point of view, of course. Some outputs are sort of
like 'set up' bits, such as the R/W line on an LCD display. You can
flip 'em around all you want, as long as they are set up properly
JUST PRIOR to actually issuing a device command. Sharing a single
output line in such a case makes a lot of sense, but it is not immediately
evident to some people that this is allowable.


*       Normal and inverted serial output (Q and /Q)
Usually you just use the normal Q output. This will become our serial
input. As mentioned above, Q will follow the state of the rightmost
bit whenever Shift /Load is low. Immediately following a /Load pulse,
Q will show the latched state of the rightmost parallel input.
Following each Clock pulse the data at Q will reflect the 'latched'
state of the next bit.

Sneaky Trick (4)
You might be wondering whether or not you can 'share' a single
PIC input to handle this and another device. You can, but it requires
some way of determining which input is 'active'. Here is where you
can use the same PIC output that controls Shift /Load to do double duty!
Whenever you are outputting a HIGH to the Shift /Load control, you could
use that same high to control a two-input multiplexer such that it
directs the Q output data into the PIC serial input port. If using
trick (3B) in this context, you CANNOT also use trick (3A), since
activating /Load would disable the Q from getting to the PIC port.
If you want to use trick (3A), you would have to control the
multiplexer with some other PIC output bit.

****

Now that you understand the operation of the 74165, let's look at what PIC
resources are required to use it. Remember that you *may* be able to share the
PIC resources with other devices.

PIC PORT REQUIREMENTS FOR PARALLEL to SERIAL INPUT PORT

Two outputs, one input. (PS_IN stands for Parallel to Serial INput device)
Outputs:        PS_IN_CLOCK and PS_IN_SHIFT_NOT_LOAD (I like descriptive names).
Input:  PS_IN_SDATA

SAMPLE ROUTINE TO READ 8 BITS FROM PARALLEL TO SERIAL PORT
Assume 74165 chip used, and allow port sharing on both outputs.
Assume Clock Inhibit is tied LOW.

PS_IN_CTR                       equ     0x10    ;Parallel to Serial INput CouNTe
r
                                               ; Used to keep track of current
bit
                                               ; Use any SRAM location desired.
Sample 0x10
                                               ; *** This register can be share
d with other
                                               ; *** routines. Local Variable.
PS_IN_REG                       equ     0x11    ;Storage for 8 bit serial input
data
                                               ; Use any SRAM location desired.
Sample 0x11
PS_IN_CLOCK                     equ     0x01    ;Assign to PORTA, bit 1 (OUTPUT)
PS_IN_SHIFT_NOT_LOAD    equ     0x02    ;Assign to PORTA, bit 2 (OUTPUT)
PS_IN_DATA                      equ     0x03    ;Assign to PORTA, bit 3 (INPUT)

;Assume user has set up PIC, including PORTA I/O direction for each bit

PS_IN:                                  ;Entry Label for Parallel to Serial INpu
t
               MOVLW   D'8'                    ;8 bits to be read
               MOVWF   PS_IN_CTR               ;Save count
               BCF     PS_IN_CLOCK             ;Ensure that clock is low (may b
e shared)
               BCF     PORTA,PS_IN_SHIFT_NOT_LOAD
                                               ;That LOW latched the data for s
ure
               BSF     PORTA,PS_IN_SHIFT_NOT_LOAD
                                               ;Now we keep it high so data doe
sn't change
PS_IN_LOOP:
               BTFSS   PORTA,PS_IN_DATA        ;Read serial data from port one
bit at a time
               GOTO    GOT_ZERO
               BSF     STATUS,C                ;Load a 1 into carry if bit was
a 1
               GOTO    SHIFT_IN
GOT_ZERO:
               BCF     STATUS,C                ;Load a 0 into carry if bit was
a 0
SHIFT_IN:
               RRC     PS_IN_REG               ;Assemble bit into right-shiftin
g byte
               BSF     PORTA,PS_IN_CLOCK       ;Shift the data in the 74165 to
get ready
                                               ; to possibly read the NEXT bit.
..
               BCF     PORTA,PS_IN_CLOCK       ;Terminate the Clock pulse!
               DECFSZ PS_IN_CTR,F      ;Update our counter
               GOTO    PS_IN_LOOP              ;If not done, do next bit
               RETURN                  ;Return with data in PS_IN_REG

There, now, that wasn't so hard, was it?
There is more than one way to skin a cat, of course, and I am sure that
there are others out there who have implemented this differently.

*****
HANDLING EXTRA NINTH BIT

With a few additions, this routine can be modified to handle ANY number of
inputs, though you would usually handle multiples of 8.

To handle the '9th' bit referenced in sneaky trick (1), requires some
additional code. Here is the simplest way:

Assume user has defined a register called SOME_REGISTER, and assigned
a bit position called PS_IN_NINTH_BIT

PIC PORT REQUIREMENTS FOR PARALLEL to SERIAL INPUT PORT

Two outputs, one input. (PS_IN stands for Parallel to Serial INput device)
Outputs:        PS_IN_CLOCK and PS_IN_SHIFT_NOT_LOAD (I like descriptive names).
Input:  PS_IN_SDATA

SAMPLE ROUTINE TO READ 8 BITS FROM PARALLEL TO SERIAL PORT
Assume 74165 chip used, and allow port sharing on both outputs.
Assume Clock Inhibit is tied LOW.

PS_IN_CTR                       equ     0x10    ;Parallel to Serial INput CouNTe
r
                                               ; Used to keep track of current
bit
                                               ; Use any SRAM location desired.
Sample 0x10
                                               ; *** This register can be share
d with other
                                               ; *** routines. Local Variable.
PS_IN_REG                       equ     0x11    ;Storage for 8 bit serial input
data
                                               ; Use any SRAM location desired.
Sample 0x11

SOME_REGISTER           equ     0x12    ;We need one bit of this register
PS_IN_NINTH_BIT         equ     0x07    ;Any available bit will do!

PS_IN_CLOCK                     equ     0x01    ;Assign to PORTA, bit 1 (OUTPUT)
PS_IN_SHIFT_NOT_LOAD    equ     0x02    ;Assign to PORTA, bit 2 (OUTPUT)
PS_IN_DATA                      equ     0x03    ;Assign to PORTA, bit 3 (INPUT)

;Assume user has set up PIC, including PORTA I/O direction for each bit


PS_IN:                                  ;Entry Label for Parallel to Serial INpu
t
               MOVLW   D'8'                    ;8 bits to be read
               MOVWF   PS_IN_CTR               ;Save count
               BCF     PS_IN_CLOCK             ;Ensure that clock is low (may b
e shared)
               BCF     PORTA,PS_IN_SHIFT_NOT_LOAD
                                               ;That LOW latched the data for s
ure
               BSF     PORTA,PS_IN_SHIFT_NOT_LOAD
                                               ;Now we keep it high so data doe
sn't change
PS_IN_LOOP:
               BTFSS   PORTA,PS_IN_DATA        ;Read serial data from port one
bit at a time
               GOTO    GOT_ZERO
               BSF     STATUS,C                ;Load a 1 into carry if bit was
a 1
               GOTO    SHIFT_IN
GOT_ZERO:
               BCF     STATUS,C                ;Load a 0 into carry if bit was
a 0
SHIFT_IN:
               RRC     PS_IN_REG               ;Assemble bit into right-shiftin
g byte
               BSF     PORTA,PS_IN_CLOCK       ;Shift the data in the 74165 to
get ready
                                               ; to possibly read the NEXT bit.
..
               BCF     PORTA,PS_IN_CLOCK       ;Terminate the Clock pulse!
               DECFSZ PS_IN_CTR,F      ;Update our counter
               GOTO    PS_IN_LOOP              ;If not done, do next bit
GET_BIT_9:                                      ;So far all has been exactly the
same
                                               ; as the 8 bit example. Now we a
dd the
                                               ; extra code to handle the ninth
bit.

               BCF     SOME_REGISTER,PS_IN_NINTH_BIT
                                               ;Assume it's a 0
               BTFSS PORTA,PS_IN_DATA  ;Get extra (for free!) ninth bit
               GOTO    PS_IN_RET               ;If it was a 0, we are already d
one!
               BSF     SOME_REGISTER,PS_IN_NINTH_BIT
                                               ;If it was a 1, make it so!
PS_IN_RET:
               RETURN                  ;Return with data in PS_IN_REG


*****
HANDLING MULTIPLES OF 8 BITS

To handle multiples of 8 bits you would use FSR and indirect addressing
to load first 8 bits into one register, then the next 8 into the
next register, etc.  References to PS_IN_REG would be changed to references
to INDF. Obviously FSR would have to be initially loaded with the
address of the first storage register, and FSR would have to be incremented
after 8 bits have been loaded.

The best way to implement that would be to have a routine that called
the generic 8 bit routine using INDF twice, each time with FSR containing
a different register address.

PIC PORT REQUIREMENTS FOR N*8 PARALLEL to SERIAL INPUT PORT

Two outputs, one input. (PS_IN stands for Parallel to Serial INput device)
Outputs:        PS_IN_CLOCK and PS_IN_SHIFT_NOT_LOAD (I like descriptive names).
Input:  PS_IN_SDATA

SAMPLE ROUTINE TO READ MULTIPLES of 8 BITS FROM PARALLEL TO SERIAL PORT
Assume 74165 chips used, and allow port sharing on both outputs.
Assume Clock Inhibit is tied LOW.

PS_IN_CTR                       equ     0x10    ;Parallel to Serial INput CouNTe
r
                                               ; Used to keep track of current
bit
                                               ; Use any SRAM location desired.
Sample 0x10
                                               ; *** This register can be share
d with other
                                               ; *** routines. Local Variable.
PS_IN_REG1                      equ     0x11    ;Storage for 8 bit serial input
data
                                               ; Use any SRAM location desired.
Sample 0x11
PS_IN_REG2                      equ     0x12    ;Storage for 8 bit serial input
data
                                               ; should be contiguous with PS_I
N_REG1
PS_IN_CLOCK                     equ     0x01    ;Assign to PORTA, bit 1 (OUTPUT)
PS_IN_SHIFT_NOT_LOAD    equ     0x02    ;Assign to PORTA, bit 2 (OUTPUT)
PS_IN_DATA                      equ     0x03    ;Assign to PORTA, bit 3 (INPUT)

;Assume user has set up PIC, including PORTA I/O direction for each bit

PS_IN_FSR:                                      ;This allows multi-byte transfer
s.
               MOVLW   PS_IN_REG1
               MOVWF   FSR                     ;Point to PS_IN_REG1 for 1st byt
e
               CALL    PS_IN                   ;Do it!

               INCF    FSR,F                   ;Point to next register, PS_IN_R
EG2
               CALL    PS_IN                   ;Do it, too!
               RETURN                  ;That's all, folks!



PS_IN:                                  ;Entry Label for Parallel to Serial INpu
t
               MOVLW   D'8'                    ;8 bits to be read
               MOVWF   PS_IN_CTR               ;Save count
               BCF     PS_IN_CLOCK             ;Ensure that clock is low (may b
e shared)
               BCF     PORTA,PS_IN_SHIFT_NOT_LOAD
                                               ;That LOW latched the data for s
ure
               BSF     PORTA,PS_IN_SHIFT_NOT_LOAD
                                               ;Now we keep it high so data doe
sn't change
PS_IN_LOOP:
               BTFSS   PORTA,PS_IN_DATA        ;Read serial data from port one
bit at a time
               GOTO    GOT_ZERO
               BSF     STATUS,C                ;Load a 1 into carry if bit was
a 1
               GOTO    SHIFT_IN
GOT_ZERO:
               BCF     STATUS,C                ;Load a 0 into carry if bit was
a 0
SHIFT_IN:
               RRC     INDF                    ;Assemble bit into right-shiftin
g byte
                                               ; Indirect addressing handles mu
lti bytes
               BSF     PORTA,PS_IN_CLOCK       ;Shift the data in the 74165 to
get ready
                                               ; to possibly read the NEXT bit.
..
               BCF     PORTA,PS_IN_CLOCK       ;Terminate the Clock pulse!
               DECFSZ PS_IN_CTR,F      ;Update our counter
               GOTO    PS_IN_LOOP              ;If not done, do next bit
               RETURN                  ;Return with data in register pointed to
by FSR



File away for future reference.

Hope this helps,
Fr. Tom McGahee

----------
> From: Stewart McCallum <.....pdpKILLspamspam@spam@PC-LAND.COM>
> To: PICLISTspamKILLspamMITVMA.MIT.EDU
> Subject: Shift Registers & Stamps
> Date: Thursday, June 18, 1998 12:37 AM
>
> Can anyone shed some light on using shift registers with stamps to control
outputs and inputs.
>
> Any help would be appreciated.
> Stewart McCallum
> Vancouver, Canada

1998\06\18@182143 by William Chops Westfield

face picon face
Does something like a 22V10 (ok, specifically a 22V10) contain enough buried
state to make an internal shift register with external latches? (ie shift in
8 data bits in a "buried" shift register, and then on your 9th clock latch
those values out to the actual pins...)

BillW

1998\06\18@210727 by Thomas McGahee

flavicon
face
Bill,
I am not familiar with the 22V10 at this time.

Maybe someone who knows more about the inner workings of the 22V10 can
help you.

You can form shift registers from several types of flip flops. You can use
RS and D type and JK types. Look in a databook for the logic structure of the
74165. The shift elements are basically 8 JK flip flops with set/reset
capability. The rest is just and/nand/nor gates.

Sorry I cannot be of more help at this time.
Fr. Tom McGahee

----------
{Quote hidden}

1998\06\19@044856 by Leon Heller

flavicon
picon face
In message <22410047102414spamspam_OUTsigmais.com>, Thomas McGahee
<@spam@tom_mcgaheeKILLspamspamSIGMAIS.COM> writes
>Bill,
>I am not familiar with the 22V10 at this time.
>
>Maybe someone who knows more about the inner workings of the 22V10 can
>help you.
>
>You can form shift registers from several types of flip flops. You can use
>RS and D type and JK types. Look in a databook for the logic structure of the
>74165. The shift elements are basically 8 JK flip flops with set/reset
>capability. The rest is just and/nand/nor gates.

I've just tried putting a '165 into an ispGAL22V10 using the Lattice
Synario software. The fitter reported plenty of spare capacity -
utilisation was 20%.

Leon
--
Leon Heller: KILLspamleonKILLspamspamlfheller.demon.co.uk http://www.lfheller.demon.co.uk
Amateur Radio Callsign G1HSM    Tel: +44 (0) 118 947 1424
See http://www.lfheller.demon.co.uk/dds.htm for details of a simple AD9850
DDS system. See " "/diy_dsp.htm for a simple DIY DSP ADSP-2104 system.

More... (looser matching)
- Last day of these posts
- In 1998 , 1999 only
- Today
- New search...