EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Just one pin to control a shift register

Started by Unknown March 3, 2008
I'm just a novice really in embedded systems, and I'm doing a college
project. I've already gotten my board made and already stuffed it with
components, so the time for backtracking the design has been and gone.
My design might not be brilliant, but I hope it will work in the end.
Here goes...

I have an 8-Bit shift register chip, and at any time there will only
be one HIGH on it. For instance:

1000000
0100000
0010000
0001000
0000100
0000010
0000001

Each shift-register pin will go to a single LED, and the HIGH will be
used to power one LED at a time. The shift register will be clocked so
fast that I'll have 8 LED's that will look like they're all on at the
same time.

Now I could have done this fairly easily using TWO pins from my
microcontroller. The first pin would go to the actual shift register
input, and the second pin would go to the clock input on the shift
register. (An RC circuit would be put on the shift register's master
reset to make sure that we start off with all zeroes). When the
micrcontroller boots up, I would put a HIGH onto the input, clock it,
then set the input low, then clock it a further six times, then set
the input high again, clock it, set the input low, then clock it a
further six times, ad infinitum.

Being an ambitious, excited student tho and not really knowing better,
I decided to achieve my goal using only one pin from the shift
register. Here's how I designed it:

On the input to the shift register, I put an OR gate. One input to the
OR gate goes to an RC, and the other input to the OR gate is tied back
to the last pin on the shift register. The idea is that I use the RC
to provide a 1 to shift onto the shift register at the very beginning,
and then just clock the shift register in an eternal loop, where the
shift register's final 1 falls off the end, goes thru the OR gate and
back onto the first pin of the shift register. Being more specific:

1) Power is applied to the circuit

Current state of shift register: 00000000

2) While the RC circuit on the shift register's master reset hasn't de-
asserted yet, the microcontroller powers up and sets all its pins in a
known state.

Current state of shift register: 00000000

3) The master reset RC de-asserts.

Current state of shift register: 00000000

4) Before the RC that goes into the OR gate de-asserts, the
micrcontroller clocks the 1 onto the shift register.

Current state of shift register: 10000000

5) The microcontroller waits for the RC input to the OR gate to de-
assert.

Current state of shift register: 10000000

6) Now the microcontroller can clock the shift register as much as it
wants, and the 1 will be moved around in an eternal loop. (Remember,
the 8th pin on the shift register is tied back to the OR gate, meaning
that the 1 will come back around to the beginning.)

Firstly, I was warned that I shouldn't rely on the 1 being shifted
around ad infinitum because a bit of static electricity could ruin
everything, but of course being over-enthusiastic with my design, I
ignored the advice. Thankfully I haven't come across any problems on
this front yet tho, so fingers crossed.

The problem I'm having is to do with the RC circuits. I need two RC's:
One on the input to the shift register's master reset, and another on
the input to the OR gate which goes into the shift-register's input.
My idea for the timeline is something like as follows:

1) Power is applied to the circuit.
2) 20 milliseconds later, my microcontroller comes to life and
executes its first instruction. The first intructions I give it are to
set all the pins in a known state. The reason I do this is that I want
the shift register clock to be low before the shift register master
reset is de-asserted, because if it's high or if it's high impedence
then I think I might get undefined behaviour (e.g. the SR might think
there's a rising edge when really there isn't and it might actually
start shifting).
3) The SR's master reset de-asserts, so that I can actually control
the SR.
4) The microcontroller clocks the 1 onto the SR.
5) The microcontroller waits for the SR input to go low.
5) Now the microcontroller can clock the SR to its heart's content,
flashing the LED's in an eternal loop.

Now the current obstacle I need to get by is how to choose the values
for the RC's. I wanted the master reset on the shift register to stay
low for about 200 ms, and then go high (the master reset is active-
low). At the moment in my circuit, I have for this: R = 22 kilo-ohms,
C = 20 microfarrads. The product of these two yields a time constant
of 220 milliseconds. Now, I understand that you don't get a "brick
wall" effect with an RC, but I'd like to know how I should go about
picking values. Let's say that I definitely want the RC to be asserted
at 200 milliseconds, and that I want it to be deasserted before 800
milliseconds, well what time constant would I want? And hence what
component values? Do I want a time constant of 200 ms, or perhaps do I
want a multiple of that?

For the input to the OR gate, I want it to still be asserted at 1 s,
but I want it to be de-asserted by 2 s. Again, how do I go about
choosing values for the RC?

Just another thing. The microcontroller I'm using is the PIC16F684.
I've heard that it takes 20 ms to "boot up" but I haven't gotten any
concrete evidence. Does anyone know exactly how long it takes? Also,
how much space should I give myself to allow the PIC to boot up and to
have all of its pins in a known state, I went with 200 ms to give
myself plenty of room. Is this enough time, do you think?

Again, as I said, the die is cast so there's not much point telling me
what I should or shouldn't have done... what I'm trying to do is get
the current design working. And I *do* think I can get it working.

Thanks for reading!
Tom�s � h�ilidhe wrote:
> I'm just a novice really in embedded systems, and I'm doing a college > project. I've already gotten my board made and already stuffed it with > components, so the time for backtracking the design has been and gone. > My design might not be brilliant, but I hope it will work in the end. > Here goes... >
ah, no. The time for making mods to the board has just begun! Jumper a pin from the PIC to the SR so that you clock it properly. And reset it properly, while you're at it. College is not the place for shoddy design - wait 'till you're older ;-) Bob
> I have an 8-Bit shift register chip, and at any time there will only > be one HIGH on it. For instance: > > 1000000 > 0100000 > 0010000 > 0001000 > 0000100 > 0000010 > 0000001 > > Each shift-register pin will go to a single LED, and the HIGH will be > used to power one LED at a time. The shift register will be clocked so > fast that I'll have 8 LED's that will look like they're all on at the > same time. > > Now I could have done this fairly easily using TWO pins from my > microcontroller. The first pin would go to the actual shift register > input, and the second pin would go to the clock input on the shift > register. (An RC circuit would be put on the shift register's master > reset to make sure that we start off with all zeroes). When the > micrcontroller boots up, I would put a HIGH onto the input, clock it, > then set the input low, then clock it a further six times, then set > the input high again, clock it, set the input low, then clock it a > further six times, ad infinitum. > > Being an ambitious, excited student tho and not really knowing better, > I decided to achieve my goal using only one pin from the shift > register. Here's how I designed it: > > On the input to the shift register, I put an OR gate. One input to the > OR gate goes to an RC, and the other input to the OR gate is tied back > to the last pin on the shift register. The idea is that I use the RC > to provide a 1 to shift onto the shift register at the very beginning, > and then just clock the shift register in an eternal loop, where the > shift register's final 1 falls off the end, goes thru the OR gate and > back onto the first pin of the shift register. Being more specific: > > 1) Power is applied to the circuit > > Current state of shift register: 00000000 > > 2) While the RC circuit on the shift register's master reset hasn't de- > asserted yet, the microcontroller powers up and sets all its pins in a > known state. > > Current state of shift register: 00000000 > > 3) The master reset RC de-asserts. > > Current state of shift register: 00000000 > > 4) Before the RC that goes into the OR gate de-asserts, the > micrcontroller clocks the 1 onto the shift register. > > Current state of shift register: 10000000 > > 5) The microcontroller waits for the RC input to the OR gate to de- > assert. > > Current state of shift register: 10000000 > > 6) Now the microcontroller can clock the shift register as much as it > wants, and the 1 will be moved around in an eternal loop. (Remember, > the 8th pin on the shift register is tied back to the OR gate, meaning > that the 1 will come back around to the beginning.) > > Firstly, I was warned that I shouldn't rely on the 1 being shifted > around ad infinitum because a bit of static electricity could ruin > everything, but of course being over-enthusiastic with my design, I > ignored the advice. Thankfully I haven't come across any problems on > this front yet tho, so fingers crossed. > > The problem I'm having is to do with the RC circuits. I need two RC's: > One on the input to the shift register's master reset, and another on > the input to the OR gate which goes into the shift-register's input. > My idea for the timeline is something like as follows: > > 1) Power is applied to the circuit. > 2) 20 milliseconds later, my microcontroller comes to life and > executes its first instruction. The first intructions I give it are to > set all the pins in a known state. The reason I do this is that I want > the shift register clock to be low before the shift register master > reset is de-asserted, because if it's high or if it's high impedence > then I think I might get undefined behaviour (e.g. the SR might think > there's a rising edge when really there isn't and it might actually > start shifting). > 3) The SR's master reset de-asserts, so that I can actually control > the SR. > 4) The microcontroller clocks the 1 onto the SR. > 5) The microcontroller waits for the SR input to go low. > 5) Now the microcontroller can clock the SR to its heart's content, > flashing the LED's in an eternal loop. > > Now the current obstacle I need to get by is how to choose the values > for the RC's. I wanted the master reset on the shift register to stay > low for about 200 ms, and then go high (the master reset is active- > low). At the moment in my circuit, I have for this: R = 22 kilo-ohms, > C = 20 microfarrads. The product of these two yields a time constant > of 220 milliseconds. Now, I understand that you don't get a "brick > wall" effect with an RC, but I'd like to know how I should go about > picking values. Let's say that I definitely want the RC to be asserted > at 200 milliseconds, and that I want it to be deasserted before 800 > milliseconds, well what time constant would I want? And hence what > component values? Do I want a time constant of 200 ms, or perhaps do I > want a multiple of that? > > For the input to the OR gate, I want it to still be asserted at 1 s, > but I want it to be de-asserted by 2 s. Again, how do I go about > choosing values for the RC? > > Just another thing. The microcontroller I'm using is the PIC16F684. > I've heard that it takes 20 ms to "boot up" but I haven't gotten any > concrete evidence. Does anyone know exactly how long it takes? Also, > how much space should I give myself to allow the PIC to boot up and to > have all of its pins in a known state, I went with 200 ms to give > myself plenty of room. Is this enough time, do you think? > > Again, as I said, the die is cast so there's not much point telling me > what I should or shouldn't have done... what I'm trying to do is get > the current design working. And I *do* think I can get it working. > > Thanks for reading!
Tom�s � h�ilidhe wrote:
> I'm just a novice really in embedded systems, and I'm doing a college > project. I've already gotten my board made and already stuffed it with > components, so the time for backtracking the design has been and gone.
On the contrary. Now is exactly the time to think *hard* what will be the better choice: the one that seems easy _now_, or the one that will work better in the long run.
> My design might not be brilliant, but I hope it will work in the end.
Hope is just about the only thing that keeps this thing together in the first place. Doing what you just did without very good reasons forbidding all other options is just about as bad as design can be.
> 4) Before the RC that goes into the OR gate de-asserts, the > micrcontroller clocks the 1 onto the shift register. > > Current state of shift register: 10000000
So in a nutshell, you've just bet the farm on a race between an RC circuit of unknown initial state (how *would* you know the charge in that C at the moment power was turned back on?) against the bootup time of your microcontroller (how do you know how long its oscillator took to start oscillating properly?). "Courageous" would be about the nicest thing such a plan could be called.
> 5) The microcontroller waits for the RC input to the OR gate to de- > assert.
And how does it do that without being connected to it?
That was a lot and honestly, I didn't read all the way to the end, but
I did read about how you expect the circuit to work.  You had been
warned about the loop not being tolerant of any upsets and that is a
potential issue.  But there is a way out.  You may have to white wire
a few connections, but you should be able to make this work.

You don't need the OR gate at all.  Instead of the RC on the data
input using power, it should be connected to the clock line.  Then the
MCU can shift a one into the register by holding the line high and
clocking it low for a very short time before going high again.  The RC
will filter this brief low time to the data pin so it will shift in a
one.  To shift in subsequent zeros, the clock line needs to be brought
low immediately and high again after the RC has brought the data line
low.  In essence, the RC filter allows the decoding of a PWM encoded
clock and data.

Your scheme should work ok as long as you know all of the time
delays.  But the PWM approach should be more reliable.

On Mar 3, 6:40 pm, Tom=E1s =D3 h=C9ilidhe <t...@lavabit.com> wrote:
> I'm just a novice really in embedded systems, and I'm doing a college
=2E..snip...
Thank you everyone for your replies.

Here's how I've decided what RC values to choose:

Firstly, I needed to find out how many time constants it would take
before I could no longer rely on the RC being asserted. Given that 5 V
is high, and 0 V is low, I decided to pick 4 V as the point below
which I can't rely on it being high, and 1 V as the point above which
I can't rely on it being low.

4 V is 80% of 5 V. In order to figure out how long it would take for
the 5 V to become 4 V, I had to find out the amount of time constants
it would take to result in the voltage being 80% of its original
value. All I had to do was get the inverse natural log of .8, and this
turned out to be .223144.

1 V is 20% of 5 V. So I got the inverse natural log of .2 which turned
out to be 1.6094.

Using this info, I was able to put together the following RC's:

Master Reset: C = 22 microfarads. R = 10 kilo-ohms. Time constant =
220 ms. Guaranteed high before 50 ms. Guaranteed low after 354 ms.

SR input: C = 100 microfarads. R = 16.5 kilo-ohms. Time constant =
1.65 s. Guaranteed high before 368 ms. Guaranteed low after 2.7
seconds.

Of course, it's not great that my board will take 2.7 seconds to boot
up... but I can live with it.

What do people think of my choices of 4 V and 1 V as the threshold for
high and low? Do you think this reliable? Or perhaps do you think I
can push it even further, maybe to 3V and 2V?

Any comments, questions, or suggestions welcomed.
> You don't need the OR gate at all. =A0Instead of the RC on the data > input using power, it should be connected to the clock line. =A0Then the > MCU can shift a one into the register by holding the line high and > clocking it low for a very short time before going high again. =A0The RC > will filter this brief low time to the data pin so it will shift in a > one.
If you turn the clock input and the data input into the same node in the circuit, then surely the RC at that node will affect both of these inputs equally, no? I mean, if the RC stops the input from dropping low, then surely it will also stop the clock from dropping low? Or do I misunderstand?
On Mar 5, 7:34 am, Tom=E1s =D3 h=C9ilidhe <t...@lavabit.com> wrote:
> > You don't need the OR gate at all. Instead of the RC on the data > > input using power, it should be connected to the clock line. Then the > > MCU can shift a one into the register by holding the line high and > > clocking it low for a very short time before going high again. The RC > > will filter this brief low time to the data pin so it will shift in a > > one. > > If you turn the clock input and the data input into the same node in > the circuit, then surely the RC at that node will affect both of these > inputs equally, no? I mean, if the RC stops the input from dropping > low, then surely it will also stop the clock from dropping low? > > Or do I misunderstand?
Yes, you misunderstand. Think of how you apply the RC filter, it has an input and an output. The clock input should be driven directly from the MCU output. The data pin will be driven from the output of the RC filter.
On Mar 5, 7:28 am, Tom=E1s =D3 h=C9ilidhe <t...@lavabit.com> wrote:
> Thank you everyone for your replies. > > Here's how I've decided what RC values to choose: > > Firstly, I needed to find out how many time constants it would take > before I could no longer rely on the RC being asserted. Given that 5 V > is high, and 0 V is low, I decided to pick 4 V as the point below > which I can't rely on it being high, and 1 V as the point above which > I can't rely on it being low. > > 4 V is 80% of 5 V. In order to figure out how long it would take for > the 5 V to become 4 V, I had to find out the amount of time constants > it would take to result in the voltage being 80% of its original > value. All I had to do was get the inverse natural log of .8, and this > turned out to be .223144. > > 1 V is 20% of 5 V. So I got the inverse natural log of .2 which turned > out to be 1.6094.
I am not clear on what you want to use these two numbers for. I don't think you did the calculation correctly to determine the times for a one or a zero output given an RC. But maybe I don't understand what you are doing here. One time constant is when the RC reaches 60+% (I don't recall the exact number). 80% and 20% are valid values to use for CMOS logic. 1V will be too high for TTL logic.
> Using this info, I was able to put together the following RC's: > > Master Reset: C =3D 22 microfarads. R =3D 10 kilo-ohms. Time constant =3D > 220 ms. Guaranteed high before 50 ms. Guaranteed low after 354 ms. > > SR input: C =3D 100 microfarads. R =3D 16.5 kilo-ohms. Time constant =3D > 1.65 s. Guaranteed high before 368 ms. Guaranteed low after 2.7 > seconds. > > Of course, it's not great that my board will take 2.7 seconds to boot > up... but I can live with it. > > What do people think of my choices of 4 V and 1 V as the threshold for > high and low? Do you think this reliable? Or perhaps do you think I > can push it even further, maybe to 3V and 2V? > > Any comments, questions, or suggestions welcomed.
You seem to be linking the two time constants. If you go with my approach, the two are independent. I see no reason to set an RC for the clock/data line longer than a few microseconds depending on how fast your MCU runs. I expect you will use a bit banged I/O pin, but you could use a UART or other serial I/ O. A UART can be set up for 10 bits by setting 8 data bits with no parity and 1 stop bit. The start bit will always be a low and the stop bit will always be a high. Your data bits should all be the same value, 0x00 or 0xFF. Then your pulse output will be 1/10 of a character low and 9/10 high or 9/10 low and 1/10 high. At a 19.2 kbps data rate, you can set an RC of 5/19200 seconds (260 uS ~=3D 2.7k ohms and 0.1 uF) and you will get 83% of 5 volts for a high and 17% of 5 volts for a low. This may not be low enough for TTL, but you can fix that by running the RC from 3 volts rather than 5 volts. If that is not enough margin for you, the I/O would need to be synchronous (without start and stop bits) so you can use multiple characters to set the timing.
Tom=E1s =D3 h=C9ilidhe wrote:

> Thank you everyone for your replies. > > What do people think of my choices of 4 V and 1 V as the threshold for > high and low? Do you think this reliable? Or perhaps do you think I > can push it even further, maybe to 3V and 2V?
READ the device datasheets, they should tell you the MIN/MAX levels. Also be aware slow edges on reset lines, can cause strange effects if the device does not have a schmitt input. Also, if you get one bogus clock, what happens to your design ? Do you have Spice Analog simulation software ?
> > Any comments, questions, or suggestions welcomed.
Yes, read up on ONE-Wire BUS designs, and study rickman's suggestion. That is a MUCH smarter way to handle a single pin RC/Clk+Data interface. This has been done before, so learn from those who have done this already. With a simple SR, the LAST 8 bits are displayed after a clk/data burst, so you do not have to hope some bit stays alive, in a shift register. -jg

Memfault Beyond the Launch