# Just one pin to control a shift register

• posted

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.

• posted

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

• posted

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.

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.

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.

And how does it do that without being connected to it?

• posted

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 l> I'm just a novice really in embedded systems, and I'm doing a college

=2E..snip...

• posted

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.

• posted

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?

• posted

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.

• posted

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.

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.
• posted

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 ?

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

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.