EmbeddedRelated.com
Forums

SPI input port

Started by Unknown June 4, 2004
Hello,
I am trying to attach a 74HC589 8-bit parallel in/serial out shift
register to my SPI port. I have a 68HC11E0 running in expanded mode with 32K RAM
and 32K EEPROM. It is a unit called the Microcore-11 from Technological Arts.
I have read the newer White book on the SPI port and was able to figure out
how to hook up a 74HC595 to get an 8-bit output port. Where I am having the
problem is working out a few connections. I know the HC11 SCK line attaches to
the SCK line of the 589, and MISO attaches to the Qh line on the 589. My
question boils down to where does the slave select line attach? My possibilities are
the /OE line, the /SLOAD line, or the RCK line. I would like to have an 8-bit
input port and 8-bit output port attached to the SPI subsystem. Any help
would be apperciated. If anyone has a better suggestion, that would be great. I do
not need too many pins, 8 I/O would be fine. Port A is driving motors and
reading 1 bit encoders, and Port E is busy reading analog inputs. So I need just
a few extra bits that will not change any faster the once a millisecond. Most
of the time the bit will only change every 10 to 100 milliseconds. Nothing
high speed.

Thanks for your time,
Tony Stram
Electronic Technician




HI all and Tony,

I just looked at the HC589's data sheet. It won't work for your application because you need a serial-in, parallel out device, like the 74HC595. On the 595, SCK is connected to clock, MOSI to serial in, and -RST to -reset (if you care about putting the outputs into a known state on power-up). Usually, one connects the latch enable to a free output so it can be pulsed after new data is serially shifted in. Because the 595 latch enable signal is edge sensitive, the slave select line might serve that purpose. You may need to invert it to get the active edge to follow the shift sequence (as opposed to leading it).

Best regards,
Scott
wrote:
Hello,
I am trying to attach a 74HC589 8-bit parallel in/serial out shift
register to my SPI port. I have a 68HC11E0 running in expanded mode with 32K RAM
and 32K EEPROM. It is a unit called the Microcore-11 from Technological Arts.
I have read the newer White book on the SPI port and was able to figure out
how to hook up a 74HC595 to get an 8-bit output port. Where I am having the
problem is working out a few connections. I know the HC11 SCK line attaches to
the SCK line of the 589, and MISO attaches to the Qh line on the 589. My
question boils down to where does the slave select line attach? My possibilities are
the /OE line, the /SLOAD line, or the RCK line. I would like to have an 8-bit
input port and 8-bit output port attached to the SPI subsystem. Any help
would be apperciated. If anyone has a better suggestion, that would be great. I do
not need too many pins, 8 I/O would be fine. Port A is driving motors and
reading 1 bit encoders, and Port E is busy reading analog inputs. So I need just
a few extra bits that will not change any faster the once a millisecond. Most
of the time the bit will only change every 10 to 100 milliseconds. Nothing
high speed.

Thanks for your time,
Tony Stram
Electronic Technician

---------------------------------
Yahoo! Groups Links

To
---------------------------------


--- In , Stramkb9mrm@a... wrote:
> Hello,
> I am trying to attach a 74HC589 8-bit parallel in/serial out shift
> register to my SPI port.

The '589 is a good choice for a serially-driven input port, but if
you want to read and control it with a single SELECT output, I think
you will need to add at least one inverter.

Note that I have NOT tried this, but I think it will work, based on
what I read regarding the 74HC589:

Connect HC11 SCK to '589 SCK.
Connect HC11 MISO to '589 Qh.
Connect HC11 MOSI to '589 SER (optional).
Connect HC11 PD5[*] to '589 RCK and -OE, and inverter input.
Connect inverter output to -SLOAD.

[*] The port output does NOT have to be PD5/-SS. It can be any port
line that can be configured as an output.

Since the '589's RCK (parallel input to shift register load) is
positive-edge triggered, the procedure you will need to follow to
read the inputs will be somewhat unusual. Before you initiate a SPI
transfer, you will need to pulse the select line once before you
bring it low for the duration of the SPI transfer. Assuming you are
using PD5 as your select line, and have the '589 wired as suggested
above, the procedure would be:

PD5 = LOW
PD5 = HIGH (at this point, inputs are xfer'd to shift register)
PD5 = LOW (Qh enabled, ready to transmit)
Initiate SPI transfer with PD5 = LOW
After transfer is complete, bring PD5 = HIGH

Unfortunately, the design of the '589 is such that the -SLOAD input
must be HIGH while a serial transfer is taking place. This is why
the inverter ('HC00 or 'HC04) is required. Also, there may be
internal propagation delay issues with the approach I have just
discussed. You *may* find it necessary to pulse the select output
TWICE (LOW-HIGH-LOW-HIGH-LOW) to ensure that the shift register is
loaded with the current input pin states before you start the
transfer.

You could, of course, use TWO outputs to control the '589's latching
action - one output connected to -SLOAD, the other to RCK and -OE.
Assuming that PA3 is connected to -SLOAD, and PD5 is connected to
RCK and -OE, the read procedure would be:

PD5 = LOW
PA3 = LOW
PD5 = HIGH (inputs transfered to shift register)
PA3 = HIGH (-SLOAD inactive so serial xfer can take place)
PD5 = LOW (-OE active, Qh enabled)
Initiate SPI transfer
When transfer complete, PD5 = HIGH

If you are using multiple '589's, you can share the output
controlling -SLOAD with all ('589) devices on the bus.

You also mentioned that you were interested in creating outputs
using a serial-in-parallel-out (SIPO) device. The 74HC594 or
74HC595 can be used for this purpose. The '594 offers a -RCLR input
that (if connected to -RESET) will clear the output latch when your
board is reset. The '595 replaces -RCLR with a -OE line that allows
you to tri-state the outputs. Otherwise, the devices are identical.

To use the '594/'595 as a serially-driven output port, connect it
thus:

System -RESET to '594 -RCLR
HC11 SCK to '594/5 SCK
HC11 MOSI to '594/5 SER
HC11 PD5[*] to '594/5 RCK

[*] Any HC11 output can be used to control RCK

The '594/5 is not 'selected' in the usual sense of the term. The
internal shift register will always be shifted upon each clock
pulse. However, the shift register contents will not be transferred
to the outputs until a low-to-high transition takes place on the RCK
input. Thus, it is still possible to place multiple '594/5's on a
serial bus as long as each one has its own dedicated RCK signal.
You can also 'daisy chain' multiple '594/5's using a -Qh to SER
connection, with a common RCK connection - but I won't go over the
procedure for this approach now.

The procedure for loading the '594/5 with new data is:

Set PD5 (RCK) = LOW
Load SPDR with desired output data, initiate SPI transfer
After transfer is complete, set PD5 (RCK) = HIGH

If your setup is using both a '589 for input and a '594/5 for
output, you can, if you are careful, use the same output
that 'selects' the '589 to drive the '594/5's RCK. To achieve this,
you must send out your output data (to the '594/5) at the same time
you read your inputs from the '589. You must ensure that you load
the SPDR with the desired state of your '594/5 outputs every time
you do a SPI transfer, even if all you really want to do is read the
inputs from the '589. The procedure I outlined for reading the '589
will also serve to load the '594/5.

I hope this answers your question(s). If you have any questions
regarding what I've discussed above, feel free to ask.


First I would like to thank everyone for their responses.

n9xmj,

You think their might be internal propagation delays for the '589? What if I
tried this in code:
PD5 = LOW
PD5 = HIGH
add a few NOP's
PD5 = LOW
instead of the L-H-L-H-L ? I normally program in "C", but I am getting better
at assembly. I figured out how to control the SPI port in assembly. Once you
set up the registers correctly, the rest was easy. I just put my data into a
variable, call my subroutine, and I am done.

I am going to use the '595 and '589 because of the tri-state ability of the
chips. Some of my I/O lines will be bi-directional. I might end up using 2
seperate pins to control the /OE lines so I can tri-state the devices at specific
times.

The end point to this is a small mobile robot. It is just a hobby, and I
wanted to try building one. Most of the electronics and code are complete. I ran
into needing a few more I/O. I think that is always the case with
microcontrollers. The SPI port looked like my best bet.

Well, again thanks everyone.

Tony Stram
Electronic Technician




Hi Tony.

This is the method I have been using for many
years, to connect the HC589's. I often have many
devices cascaded, the OE is connected only to
the last 589 in the chain.

__________________________________________
\
OE \
\________

_____ ________ _____________
\ / \ /
RCLK \ / \ /
SRLOAD \_______/ \________/

^ ^ ^
Latch input load shif reg shift out data If you connect the serial out of the last 595 you
can feed into the 589's to do a loop test. This
can help to count how many devices are in the chain
if you system can be expanded also.

Darren Moore > -----Original Message-----
> From: [mailto:]
> Sent: Friday, 4 June 2004 23:02
>
> Hello,
> I am trying to attach a 74HC589 8-bit parallel
> in/serial out shift
> register to my SPI port. I have a 68HC11E0 running in
> expanded mode with 32K RAM
> and 32K EEPROM. It is a unit called the Microcore-11 from
> Technological Arts.
> I have read the newer White book on the SPI port and was
> able to figure out
> how to hook up a 74HC595 to get an 8-bit output port. Where I
> am having the
> problem is working out a few connections. I know the HC11 SCK
> line attaches to
> the SCK line of the 589, and MISO attaches to the Qh line on
> the 589. My
> question boils down to where does the slave select line
> attach? My possibilities are
> the /OE line, the /SLOAD line, or the RCK line. I would like
> to have an 8-bit
> input port and 8-bit output port attached to the SPI
> subsystem. Any help
> would be apperciated. If anyone has a better suggestion, that
> would be great. I do
> not need too many pins, 8 I/O would be fine. Port A is
> driving motors and
> reading 1 bit encoders, and Port E is busy reading analog
> inputs. So I need just
> a few extra bits that will not change any faster the once a
> millisecond. Most
> of the time the bit will only change every 10 to 100
> milliseconds. Nothing
> high speed.
>
> Thanks for your time,
> Tony Stram
> Electronic Technician




--- In , Stramkb9mrm@a... wrote:
...
> You think their might be internal propagation delays for the '589?
> What if I tried this in code:
> PD5 = LOW
> PD5 = HIGH
> add a few NOP's
> PD5 = LOW
> instead of the L-H-L-H-L ?

Having looked at the message I posted earlier, and re-thinking over
the procedure I suggested, my comment about prop. delay was probably
not relevant. Sorry for the confusion.

What I'm about to add here might clarify things, or might simply add
to the confusion. I hope it's the former ;)

Here's a simplified illustration of the internal logic of the '589
for one input:

Input --->[D] Latch [Q]--->[D] Shift Reg

The internal latch is edge-sensitive (rising edge of RCK) clocked,
whereas the shift register is a 'transparent' latch with a level-
sensitive latch enable (-SLOAD). A rising edge on RCK transfers the
state of the input(s) to the internal latch. -SLOAD is a level-
sensitive input that forces the state of the shift register to
reflect the Q-outputs of the internal latch.

If RCK and -SLOAD are tied together to one output port pin, and -OE
is tied to a different output, then the loading of the shift
register will require two pulses on the RCK/-SLOAD pin. Here's the
sequence of events:

RCK/-SLOAD = HIGH
-OE = HIGH Idle state
RCK/-SLOAD = LOW Latch -> Shift Reg (value in latch is the OLD
state of the inputs the last time you read it,
not current!)
RCK/-SLOAD = HIGH RCK sees rising edge, Inputs -> Latch. The
internal latch now has the current input state,
but the shift register does not.
RCK/-SLOAD = LOW Latch -> Shift Reg. Shift reg now has 'current'
state of inputs.
RCK/-SLOAD = HIGH -SLOAD high, so Shift Reg can shift.
-OE = LOW Ready to transfer

The above procedure follows Darren's timing diagram

In my prior message, I suggested a means by which you could use a
SINGLE output port pin to control all three '589 control inputs
(RCK, -SLOAD and -OE) by connecting RCK and -OE directly to the
output, and -SLOAD thru an inverting stage. A better arrangement
would be to route the un-inverted output to -OE, and the inverted
state to RCK and -SLOAD. The table below illustrates the sequence
of events for this configuration:

Port RCK -SLD -OE Event
---- ---- ---- ---- ------------
HIGH LOW LOW HIGH Idle state (SR = Latch, cannot shift)
LOW HIGH HIGH LOW Inputs transferred to internal latch
HIGH LOW LOW HIGH Internal latch transferred to shift register
LOW HIGH HIGH LOW Output enabled, ready to transfer
(initiate SPI transfer at this point)
HIGH LOW LOW HIGH Return to idle state after xfer complete

The above arrangement has the advantage of requiring only ONE output
to control the '589, but requires the addition of the inverter.

If you are using a large number of '589's (or '594/5's) in your
design, Darren's approach may be the better way to go, as ALL the
devices can share a common 'latch control' output, and the state of
all the inputs can be read using multiple consecutive SPI transfers
without intervening code to change output states. Darren's approach
is the most time- and code-efficient for multiple devices, but it is
not as 'selective' as the approach I outlined. Darren's method is
the most time-efficient if you want to read/update everything at
once EVERY time you want to read or change something. My approach
would incur less overhead if you I/Os are grouped in such a way that
you typically only need to read (or update) one group of 8 inputs or
outputs at a given time.

The 'double buffered' organization of the '589 and '594/5 lend
themselves to quite a few different control configurations, each
with their own pros and cons. There are doubtless many other ways
that one could wire these up; I can envision a setup that would use
a combination of the methodology I discussed along with Darren's
method; for example, creating two 16-bit input (or output) ports.
I'll go into this in more detail if interested.

> I normally program in "C", but I am getting better at assembly.
> I figured out how to control the SPI port in assembly. Once you
> set up the registers correctly, the rest was easy. I just put my
> data into a variable, call my subroutine, and I am done.

There *are* several compilers on the market (most, unfortunately,
quite expensive) that will generate HC11 code. I believe there is
even a version of the gnu/gcc compiler available that will generate
HC11/HC12 code. Most compilers that are targeted to
microcontrollers provide some sort of mechanisim to specify an
absolute address in a variable declaration, so it is possible to do
something like this:

PORTA |= 0x40;
SPIData = SPDR;
...etc...

> I am going to use the '595 and '589 because of the tri-state
> ability of the chips. Some of my I/O lines will be bi-directional.
> I might end up using 2 seperate pins to control the /OE lines so I
> can tri-state the devices at specific times.

As I noted above, the '589 and '594/5 are quite versatile devices.

> The end point to this is a small mobile robot. It is just a hobby,
> and I wanted to try building one. Most of the electronics and code
> are complete. I ran into needing a few more I/O. I think that is
> always the case with microcontrollers. The SPI port looked like my
> best bet.

I have just started working on a project that is I/O-intensive, and
I am taking a somewhat different approach. I happen to have on hand
quite a few 68HC711E20's that were used in development, all of which
have their ROMs already 'burned' and thus not useful for ordinary
single-chip work. However, one can still run code out of the
internal EEPROM if the device is started up in bootstrap mode. I
have written a small (< 512-byte) "slave controller" program that
will allow me to read/modify/write data to any HC11 memory location
using simple commands sent to the SPI or SCI, as well as execute
small programs loaded into the internal RAM. In effect, this small
program turns the HC11 into a semi-intelligent I/O controller. Once
I have the code fully debugged, I will be making it available to
anyone who wants it - I will probably upload it to the files section
of this group.