Following on from the "How to use HEF4021?" thread, I am writing about a
problem I am experiencing with
74HC165 shift registers. The '165 appears to be functionally similar to the
4021 although the pin out is different and the logic polarity of the control
lines differs.
My problem is in using multiple 74HC165s in a chain. I am experiencing
bizarre behaviour in that changing a parallel input pin level can affect the
level read from another of the parallel inputs. This happens both for
different inputs of the same IC and I have also observed that changing an
input level can also affect values read from a different chip in the chain.
My application is a control panel having 120 switches. Each group of 8
switches is mounted on it's own PCB with each switch being connected between
a parallel input pin of the 74HC165 and ground and having a 47k pullup to
5v.
The data output of a 74HC165 chip is connected to the data input of the
next chip. I have tied the data input pin of the chip furthest from the PIC
to 0v so that it is not floating. The Clock and Load/ Shift pins to of each
of the 10 ICs are connected in parallel. All Clock Inhibit pins are tied to
0v.
Since the problem may be related to layout, I shall describe my set-up in
detail. On a separate PCB about 9 inches long, I have created a 4-wire bus
for Clock, 5v, Load/Shift and 0v. These tracks are parallel to each other
0.2 inches apart (note that placing the 5v line being between the Clock and
Load/ Shift is intended to provide an element of shielding between these
signal lines on both the bus and the ribbon cables).
4-way Flat ribbon cable is used to connect from this bus to each of the 10
PCBs (ie. to each 74HC165). The longest ribbon cable is about 2 feet - the
average length being perhaps 1ft. Single core cable is used to connect the
data output of each chip to the data input of the next - no great care was
taken in running these wires between PCBs - although they are separated from
other wires by a lot of fresh air!
I have a 4-channel analogue 'scope and I notice that despite taking
reasonable care in the layout the clock pulses are getting into the Load/
Shift line. I can see the clock pulses as an approx. 1 volt peak-to-peak
signal riding on the 5v normal level of the Load/ Shift line (which is kept
high during the time that data is being clocked out). Before you jump to
the conclusion saying: "that's the problem", I should explain that I have
successfully tested each PCB individually under the same conditions of
interference on the L/S line. I have tested one board at a time, connecting
the board's 74HC165 data output directly to the PIC with it's data input
being tied to 0v. During these tests, the interference remains constant
since I leave the other cables in place with the parallel control lines
still going to all the other chips.
Tested in this way, each board on it's board works great! The problem only
occurs when I then try to connect boards together in a daisy chain. In
fact, I have successfully managed to get 3 or 4 boards chained together.
Generally speaking, it seems that the further the board is downstream of the
PIC in the chain, the greater is the probability of a data reading error
being experienced. For a given set-up, the problem generally remains
constant - ie. the error is observed affecting particular bits in the data
stream - pressing one switch results in the data stream indicating that more
than one bit has changed. Moving boards around results in the problem
"moving" elsewhere - ie. it is not related to a particular board or to a
particular bit number in the 120 bit data stream.
By the way, I am clocking at about 30KHz - speed is not really an issue - if
necessary I could use a slower speed (although 30KHz is already quite
slow!).
I appreciate that my layout is not perfect. However, it would be difficult
at this stage to further reduce interference between the lines (Any ideas?
Could I add capacitance to slow down pulse edges?) I am not convinced that
it is an interference problem. My argument is: how is it that I can
successfully test single boards or chain three of four together? If the
Load/ Shift line was receiving spikes that resulted in reloading data during
data being clocked out, surely this would also affect individual boards?
I should much appreciate any ideas as to what is going wrong or as to how I
can best isolate the problem.
>I appreciate that my layout is not perfect. However, it would be difficult
>at this stage to further reduce interference between the lines (Any ideas?
>Could I add capacitance to slow down pulse edges?) I am not convinced that
>it is an interference problem. My argument is: how is it that I can
>successfully test single boards or chain three of four together? If the
>Load/ Shift line was receiving spikes that resulted in reloading data during
>data being clocked out, surely this would also affect individual boards?
>
>I should much appreciate any ideas as to what is going wrong or as to how I
>can best isolate the problem.
Talk slow, add series resistors at the drivers, say 120 ohms, and scope the
ground pin on the farthest board relative to system. Scope VCC on the
farthest board, relative to it's own ground. You may need to beef up the
ground. Just guessing..
> My problem is in using multiple 74HC165s in a chain. I am
> experiencing bizarre behaviour in that changing a parallel input pin
> level can affect the level read from another of the parallel inputs.
The likely cause of this problem is a shifting error caused by lack
of clock coherence. Ignore the "load" line for the moment.
(All) shift registers are edge-triggered. They rely on the clock
simultaneously clocking *all* stages. There is an alternative to this
which I will mention as a solution.
> Each group of 8 switches is mounted on it's own PCB ...
> On a separate PCB about 9 inches long, I have created a 4-wire bus
> for Clock, 5v, Load/Shift and 0v. ... 4-way Flat ribbon cable is
> used to connect from this bus to each of the 10 PCBs
What you have *not* told us it the critical question; how is the CLOCK
line distributed? Is it one buffer per output, one per group of
outputs, or one whopping great buffer and all in parallel?
> Generally speaking, it seems that the further the board is downstream
> of the PIC in the chain, the greater is the probability of a data
> reading error being experienced.
That doesn't tell you a lot about the error, except that it is
statistical - i.e., the more you shift, the more likely an error!
> For a given set-up, the problem generally remains constant - ie. the
> error is observed affecting particular bits in the data stream -
> pressing one switch results in the data stream indicating that more
> than one bit has changed. Moving boards around results in the problem
> "moving" elsewhere
This tells you that it is idiosyncratic to timing/ threshold specs of
individual devices. It's another way of saying that you are running
something close to its specs!
> By the way, I am clocking at about 30KHz - speed is not really an
> issue - if necessary I could use a slower speed (although 30KHz is
> already quite slow!).
I agree. Speed is not really an issue. It's not speed, it's called
"propagation". I think good design would allow operation at maximum
rated speed anyway. Further:
Dave Vanhorn wrote:
> Talk slow, add series resistors at the drivers, say 120 ohms, and
> scope the ground pin on the farthest board relative to system. Scope
> VCC on the farthest board, relative to it's own ground. You may need
> to beef up the ground. Just guessing..
I disagree. Make the thing work, and it'll work at any speed.
The Answer (IMHO):
Your problem is that the clock is not getting to all the shift
registers at the same time. I'll bet you pounds to peanuts that the
mis-read input is at one end of a shift register. The preceeding shift
register is clocking, and its output changing, before the given SR is
clocked.
Slowing the clocking speed will do nothing for this if the clock edges
are sharp, because all the transitions occur fast. You have undoubtedly
designed it deliberately to make the transistions sharp. I do not
however recommend slowing the clock transition as this is a flakey fix.
You need to ensure no SR is clocked *before* a later one (in the
chain). The best way to do this is to make sure earlier ones are
actually clocked *later*. There are two ways to do this. One is to
feed the clock *backward* down the chain, buffering in each board. The
buffering will cause a slight delay line.
The alternative, compatible with your present topology and design of
peripheral boards, is to re-design the master board using a
non-inverting (octal) bus buffer to drive the outgoing clock lines in a
chain, starting from the *last* peripheral board. Note that in doing
so, the outgoing line is the same point from which the next buffer takes
its drive, so the loading on that line actually contributes to the
delay, which is *exactly* what you require as in the previous approach.
Also, terminate the lines on the peripheral boards. Suggest 4K7.
Suggest using HCMOS, not HCTMOS for a larger hysteresis.
--
Cheers,
Paul B.
>Douglas Reid wrote:
>
>> My problem is in using multiple 74HC165s in a chain. I am
>> experiencing bizarre behaviour in that changing a parallel input pin
>> level can affect the level read from another of the parallel inputs.
Thanks to everyone that offered suggestions. I have now solved the problem!
Paul Webster gave me the clue. Paul wrote:
> The likely cause of this problem is a shifting error caused by lack
>of clock coherence. Ignore the "load" line for the moment.
Paul is certainly correct in that it was clock skew that was causing the
problem. Each of the 74HC165 has it's clock pin connected in parallel (all
driven from a single PIC pin, to answer Paul's question). However, each
chip will have a slightly different logic threshold, resulting in each being
clocked at a different time on the rising clock edge. Interconnecting
cables will add capacitance which slow down the edge of the clock signal,
compounding the problem.
I am rather dubious of Paul's suggestion to clock each board one at a time
by adding gates to introduce delays. Surely ALL boards must be clocked at
the same time otherwise data would be lost? Paul wrote:
> You need to ensure no SR is clocked *before* a later one (in the
>chain). The best way to do this is to make sure earlier ones are
>actually clocked *later*.
Surely by clocking a board, it's most significant bit would be shifted out
into the least significant bit position of the earlier (ie. nearer to the
PIC) board - thus losing the LSB in that chip?
Dave Vanhorn wrote:
> Take slow, add series resistors at the drivers, say 120 ohms
I agree with Paul that this is NOT the solution. After giving the matter
some thought, I came to the conclusion that I had to SPEED UP the clock
rising edge. The faster edge will reduce the differences in time between
each chip being clocked.
I found the solution to be quite simple. I added a 74HC14 hex buffer
(Schmidt trigger input) between the PIC and the clock line to all the
74HC165s (only one gate of the buffer being used - ie. all IC clock pins are
still being driven in parallel). The HC buffer has a low output impedance
of approx 50 ohms which will have improved the rise time relative to direct
driving by the PIC pin (I wonder what the figure is for the PIC pin output
impedance?). This has solved my problem!
The Schmidt trigger feature on the input may not be that important -
however, it should help to ensure that multiple clock transitions are not
generated even if some noise is present on the input.
I have a book which compares output impedances of different logic families.
4000B is as high as 800 ohms (whether driving high or low) and,
interestingly, MC68HC11 output impedance is listed as 1000 ohms (when
driving high)/ 250 ohms (when driving low). Thus the HC chip may give a 20
x improvement in output impedance and will presumably also greatly reduce
the rise time of the clock edge.
An alternative idea (which I haven't tried) may be to use a pull-up resistor
to "help" the PIC drive the clock line.
How much current can a PIC output sink when the output level is low? This
would determine the minimum value of the pull-up.
The data sheet for the 74HC165 does not mention the importance of a fast
clock rise time. Does anyone have a figure for the maximum acceptable rise
time?
If I was starting again on this job, I might keep all the 74HC165s together
on the one board and wire the switches back to this board. This approach
might be more sensible than routing the signal lines to each remote board.
The drawback is slightly more wires needed - ie. 9 (8 switches plus 5v -
assuming pull-up resistors located on remote boards) compared to 6 (5v, 0v,
clock, load/shift, data in, data out) per board.
Thanks again for everyone's help and I hope that my experiences can save
other people time when using multiple shift registers!
>I found the solution to be quite simple. I added a 74HC14 hex buffer
>(Schmidt trigger input) between the PIC and the clock line to all the
>74HC165s (only one gate of the buffer being used - ie. all IC clock pins are
>still being driven in parallel). The HC buffer has a low output impedance
>of approx 50 ohms which will have improved the rise time relative to direct
>driving by the PIC pin (I wonder what the figure is for the PIC pin output
>impedance?). This has solved my problem!
>
Glad you found it. I was having a lot of trouble picturing the layout, and
obviously guessed wrong.
I'll return the consulting fee :)
Watch ringing on those lines though, you could get into the area I thought
you were in.
> I am rather dubious of Paul's suggestion to clock each board one at a
> time by adding gates to introduce delays. Surely ALL boards must be
> clocked at the same time otherwise data would be lost? Paul wrote:
>> You need to ensure no SR is clocked *before* a later one (in the
>> chain). The best way to do this is to make sure earlier ones are
>> actually clocked *later*.
You appear to have a different concept of "early" and "late" to mine!
To my mind, "early" means an input which must travel a longer path to
arrive at the end of the SR, not one which *arrives* before the others!
That given, I am sure the wisdom of my suggestion will be clear.
Evidently this has not been necessary in your case. Fine.
Interesting to note that a 74HC14 provides "stiffer" buffering than a
PIC pin which is rated to sink/ source 25/ 20mA, but ... so be it!
> The Schmidt trigger feature on the input may not be that important -
> however, it should help to ensure that multiple clock transitions are
> not generated even if some noise is present on the input.
That's certainly what they make them for, though many of us like to
use them as oscillators! ;-)
> interestingly, MC68HC11 output impedance is listed as 1000 ohms (when
> driving high)/ 250 ohms (when driving low). Thus the HC chip may give
> a 20 x improvement in output impedance and will presumably also
> greatly reduce the rise time of the clock edge.
Hey, we're talking PICs aren't we?, not Woosy chips!
> An alternative idea (which I haven't tried) may be to use a pull-up
> resistor to "help" the PIC drive the clock line.
No way JosŽ! Not with PICs. I know TTL logic used pull-ups in places
but that was s-l-o-w. One trick was to use pull-ups to "help" TTL to
achieve CMOS logic levels. The IÓC bus uses pull-ups, which is why you
must be extremely cautious using it outside its intended application of
on-PCB communication.
The big limitation of pull-ups is that a 1 k ohm pull-up will only
contribute 500 µA to keeping a line above 4.5 V (on a 5 V rail) but will
source 5 mA when ypu have to pull them low. PIC port B pull-ups (weak)
are special - they are current sources (I think).
> The data sheet for the 74HC165 does not mention the importance of a
> fast clock rise time. Does anyone have a figure for the maximum
> acceptable rise time?
But I'm not sure how critical this is. Ringing is more likely to be
a problem, so I'd go back and check termination, even if it works now!
> If I was starting again on this job, I might keep all the 74HC165s
> together on the one board and wire the switches back to this board.
> This approach might be more sensible than routing the signal lines to
> each remote board.
Pragmatic perhaps, but I tend to see the ability to distribute the
layout as the great advantage of the SRs. I would think that some
applications may justify an extra 74HC14 on each board buffering (two
series gates each) latch, data and the clock so that all boards can be
completely daisy-chained with the last board going *to* the master and
the clock propagating *back* from that master (i.e., buffered on every
board).
Of course output boards are daisy chained with the clock *following*
the data. Neat!
> The drawback is slightly more wires needed - ie. 9 (8 switches plus 5v
> - assuming pull-up resistors located on remote boards)
No, you do *not* put the pull-up on the remote board. That's another
principle, all input should be ground-referenced, so no short to ground
can short out the power.
--
Cheers,
Paul B.
> By the way, I am clocking at about 30KHz - speed is not really an
> issue - if necessary I could use a slower speed (although 30KHz is
> already quite slow!).
| I agree. Speed is not really an issue. It's not speed, it's called
|"propagation". I think good design would allow operation at maximum
|rated speed anyway. Further:
|Dave Vanhorn wrote:
> Talk slow, add series resistors at the drivers, say 120 ohms, and
> scope the ground pin on the farthest board relative to system. Scope
> VCC on the farthest board, relative to it's own ground. You may need
> to beef up the ground. Just guessing..
| I disagree. Make the thing work, and it'll work at any speed.
I would suggest that it's probably best to drive the clock wire
with sharp edges, but add a little bit of RC delay to the data
wires going between the '165's [same with '595's or '597's].
This will ensure that the clock's arrival at one '165 will not
affect the data at the next '165 immediatly, but only after a
short delay (by which time the next '165 should have latched the
old data).
Note that, in response to the question elsewhere about whether
non-simultaneous clocking would cause data loss, the answer is
that in one direction it will; in the other it won't. As for
adding the RC delays, what you're really doing in effect is
adding one bit of short-term storage after each shift register.
Since the RC will 'automatically' change state after a short
delay, it should be transparent to the software provided the
data shift rate isn't too high.
It seems to me that driving different SR ICs with the
same clock (and data directly frm IC to IC) is asking
for trouble (it is difficult to achieve real clock cherence
between different chips).
I think a bullet-proof solution would be to clock the
even and odd SRs with different clocks (inverting
would be the most simple).
You would have to do something clever (like clocking
out all ata twice) or you would loose each last bit in
the SRs which are clocked first after the load.
I missed the start of this thread, so apologies if this is no use...
74299's are really versatile shift registers (parallel load,
bidirectional, etc...), and have extra ripple i/o pins specifically for
chaining them together, so you don't lose data.
|74299's are really versatile shift registers (parallel load,
|bidirectional, etc...), and have extra ripple i/o pins specifically for
|chaining them together, so you don't lose data.
The 74HC299 looks like a decent chip, but is has the same
problem that the 74HC165 does: the output changes on the
same clock edge where the input is sampled. If the same
clock is fed to two shift registers which are chained to-
gether, a race condition will exist as the "downstream"
chip will try to read its input at the same time as the
"upstream" chip is changing it.
The preferred solution to this problem is to add an extra
latch between the output of one chip and the input of the
next; this latch should be triggered on the opposite clock
edge from the shift registers. There exists one parallel-
to-serial chip with this function (4094?) but I know of no
"standard" serial-to-parallel chips that work this way.
Otherwise, though, the 74HC299 looks like it might be a nice
chip for some applications, but it would be much nicer if it
included an extra set of latches so that data could be shift-
ed through it without affecting its outputs. As it is, it's
larger than a 74HC165, 74HC164, or 74HC595 and for most app-
lications it's just as functional then the '165 for input
and it's more functional than the '164 for output [since it
does have tri-statable outputs], but it's less functional than
the '595 [since it lacks double-buffering].
>
> |74299's are really versatile shift registers (parallel load,
> |bidirectional, etc...), and have extra ripple i/o pins specifically for
> |chaining them together, so you don't lose data.
>
> The 74HC299 looks like a decent chip, but is has the same
> problem that the 74HC165 does: the output changes on the
> same clock edge where the input is sampled.
Hmm... I was sure it had extra outputs that changed on the opposite
edge. (This is entirely from memory, and the page where I normally get
datasheets from seems to have vanished, so I may well be mistaken!).
> Hmm... I was sure it had extra outputs that changed on the opposite
> edge. (This is entirely from memory, and the page where I normally get
> datasheets from seems to have vanished, so I may well be mistaken!).
Index: www.st.com/stonline/books/pdf/menu/05040200.htm
74HC299: www.st.com/stonline/books/pdf/docs/1942.pdf
--
Cheers,
Paul B.
Maybe I'm missing something...wouldn't a generic 8051 give you 32 I/O
lines (plus a uart) - no shifting, etc. Price wise, you would
probably "break even" . (I haven't priced 8051s lately, but they were
fairly cheap).
The only extra part you need (assuming your using the internal clock
of some PIC chip) is a clock source, seems like they could be run
from a simple invertor thingie too...
Not to mention you have a "REAL" programming environment - at least
8K of code and 256 bytes of ram - NO BANK SWITCHING!!! Real Interrupt
support too! Ok, maybe they run a little slower...
For lots of I/O and complex programs, I think the 8051 is the way to
go...but, your millage may vary :-))
Ralph
Note:
"When the only tool you have is a hammer,
all your problems look like nails." - old quote from somebody...
>
> Following on from the "How to use HEF4021?" thread, I am writing about a
> problem I am experiencing with
> 74HC165 shift registers. The '165 appears to be functionally similar to the
> 4021 although the pin out is different and the logic polarity of the control
> lines differs.
>
> My problem is in using multiple 74HC165s in a chain. I am experiencing
> bizarre behaviour in that changing a parallel input pin level can affect the
> level read from another of the parallel inputs. This happens both for
> different inputs of the same IC and I have also observed that changing an
> input level can also affect values read from a different chip in the chain.
>
> My application is a control panel having 120 switches. Each group of 8
> switches is mounted on it's own PCB with each switch being connected between
> a parallel input pin of the 74HC165 and ground and having a 47k pullup to
> 5v.
>
> The data output of a 74HC165 chip is connected to the data input of the
> next chip. I have tied the data input pin of the chip furthest from the PIC
> to 0v so that it is not floating. The Clock and Load/ Shift pins to of each
> of the 10 ICs are connected in parallel. All Clock Inhibit pins are tied to
> 0v.
>
> Since the problem may be related to layout, I shall describe my set-up in
> detail. On a separate PCB about 9 inches long, I have created a 4-wire bus
> for Clock, 5v, Load/Shift and 0v. These tracks are parallel to each other
> 0.2 inches apart (note that placing the 5v line being between the Clock and
> Load/ Shift is intended to provide an element of shielding between these
> signal lines on both the bus and the ribbon cables).
>
> 4-way Flat ribbon cable is used to connect from this bus to each of the 10
> PCBs (ie. to each 74HC165). The longest ribbon cable is about 2 feet - the
> average length being perhaps 1ft. Single core cable is used to connect the
> data output of each chip to the data input of the next - no great care was
> taken in running these wires between PCBs - although they are separated from
> other wires by a lot of fresh air!
>
> I have a 4-channel analogue 'scope and I notice that despite taking
> reasonable care in the layout the clock pulses are getting into the Load/
> Shift line. I can see the clock pulses as an approx. 1 volt peak-to-peak
> signal riding on the 5v normal level of the Load/ Shift line (which is kept
> high during the time that data is being clocked out). Before you jump to
> the conclusion saying: "that's the problem", I should explain that I have
> successfully tested each PCB individually under the same conditions of
> interference on the L/S line. I have tested one board at a time, connecting
> the board's 74HC165 data output directly to the PIC with it's data input
> being tied to 0v. During these tests, the interference remains constant
> since I leave the other cables in place with the parallel control lines
> still going to all the other chips.
>
> Tested in this way, each board on it's board works great! The problem only
> occurs when I then try to connect boards together in a daisy chain. In
> fact, I have successfully managed to get 3 or 4 boards chained together.
> Generally speaking, it seems that the further the board is downstream of the
> PIC in the chain, the greater is the probability of a data reading error
> being experienced. For a given set-up, the problem generally remains
> constant - ie. the error is observed affecting particular bits in the data
> stream - pressing one switch results in the data stream indicating that more
> than one bit has changed. Moving boards around results in the problem
> "moving" elsewhere - ie. it is not related to a particular board or to a
> particular bit number in the 120 bit data stream.
>
> By the way, I am clocking at about 30KHz - speed is not really an issue - if
> necessary I could use a slower speed (although 30KHz is already quite
> slow!).
>
> I appreciate that my layout is not perfect. However, it would be difficult
> at this stage to further reduce interference between the lines (Any ideas?
> Could I add capacitance to slow down pulse edges?) I am not convinced that
> it is an interference problem. My argument is: how is it that I can
> successfully test single boards or chain three of four together? If the
> Load/ Shift line was receiving spikes that resulted in reloading data during
> data being clocked out, surely this would also affect individual boards?
>
> I should much appreciate any ideas as to what is going wrong or as to how I
> can best isolate the problem.
>
> Thanks in advance.
>
> Regards,
> Doug