8 bit Parallel I/O - is there an easy (and efficient) way to do it?

I've been trying to find a way to do fast 8 bit parallel I/O (bi-directional) on arduinos. All the hardware 8 bit ports seem to be compromised by having some pins devoted to other uses. For example PortD can't be used in this way because it can interfere with the IDE communication on digital pins 0 & 1, potentially locking you out of doing new program uploads.

There seems to be a general mind-set that communication should be serial even though it may mean dismantling your byte (or even unsigned long integer) in order to send it bit-at-a-time to a device that would prefer that you sent it a byte-at-a-time (I'm thinking of DDS chips such as the AD9850/1). Is this mind-set a result of the difficulty of doing parallel I/O or am I missing something?

Yes, I have read the portmanipulation page in the reference section (even though it is not in the index) - it doesn't look like it helps if you want 8 bits - input and output.

If I can get this sorted out I would like to contribute an article on 8 bit parallel I/O. Any help would be appreciated.

Andy.

Sorry about the duplicate posting - the first one didn't seem to work. :blush:

Well, you've hit one of the limitations of a chip that tries to do as much as it can with 28 pins. PORTD would be your closest to achieving that, except for the pull-ups between D0/D1 and the USB interface.

The fact is, though, that serial can be pretty fast. It can be pretty fast if you use SPI to clock out serially to something like a 74HC595 chip. Why? Once you start an SPI transfer, the data is clocked out at a maximum clock speed of 1/2 processor clock speed, so, 125 nS per bit. Thus to clock out a byte takes 1 uS (16 clock cycles).

To do it in parallel (like with the AD9850 chip) would be slightly faster, but not by an order of magnitude. You still have to set up the data into the register, and bring a clock pin high, and then low, which will take a few instructions.

For example PortD can't be used in this way because it can interfere with the IDE communication on digital pins 0 & 1, potentially locking you out of doing new program uploads.

You can connect and disconnect the pins, or use the ICSP interface for programming if you are desperate.

There seems to be a general mind-set that communication should be serial even though it may mean dismantling your byte ...

I don't know why you have to dismantle your byte. Just send the byte via SPI, rather than shoving it into PORTD. Same thing.

With all the alternate pin functions it is a bit of a head-scratcher. PortC doesn't have 8 pins, PortB has 8 pins, but only if a crystal and SPI are not being used. But 8 bits can be found using some combination of ports. Sure, it's a few more statements/instructions, and less convenient, but should not be a show-stopper. I did a seven-segment, four-digit multiplexer using PortB and PortD. I avoided the serial pins and the crystal pins, but did use the SPI pins. It's all about compromises.

Thanks Nick,

I'm glad to hear it is a limitation of the chip - in the sense that I'd rather it was the chip than me!

Do all the Arduino variants suffer from this limitation? If so, I think it is something that should be looked at for future versions.

As regards dismantling the byte (or unsigned long in the case of the AD9850), if it goes out over a serial interface (SPI or whatever) then it obviously gets dismantled somewhere along the way. I do take your point about SPI clock speeds though. That's something I hadn't picked up on previously so THANKS!

Andy.

Topics merged, duplicate post removed.

findrew:
Do all the Arduino variants suffer from this limitation? If so, I think it is something that should be looked at for future versions.

It's a design compromise. The Mega2560 board probably has more complete ports available. However as far as I can tell most chips these days are using serial, after all that lets you talk to them with a couple of pins (for I2C) or 3/4 pins (for SPI) rather than 8 for data, plus clock, etc. for parallel.

For byte-wide parallel I'd suggest the Mega is the way to go. The processor's ports A and C are actually designed for parallel use to static RAM IIRC, and there are half a dozen 8-bit ports in total that all map to pins.

I've used a counter chip with a parallel interface (the SN74LV8154) in a frequency counter and used a shift-register to make it easier to interface to (74HC299). Admittedly I only needed 4 bytes read every millisecond at most, it wasn't a high-bandwidth application like ADC/DAC or memory access might be.

Thanks everybody!

Looks like I need to read up on SPI and/or check out the Arduino Mega versions.

I would close this topic if I could see a way to do so. Since I can't, I'll bow out with this final request:

Could somebody please update the index to the reference section? Port manipulation (and who knows what else) is totally absent from the reference index page. Maybe I should start a new thread...

Andy.

Using the mega for the reason of complete 8-bit ports == higher speed might not be as great as first expected.
Ram and hi-range port access takes additional overhead and branching takes 1 extra cycle over branching on smaller atmega versions.
These overheads may cause your system to be no faster or possibly even slower than running it on the UNO.