Noise reduction in SPI

avrspi

I've been working on a project to interface ENC28J60 with an ATmega16A µC. For the sake of debugging I have built a board with UART capability so that I can view the register values of the Ethernet controller chip on my laptop. I tried to establish communication with the ENC28J60 chip and my µC through SPI and was unable to get any sort of reading even though my code seemed to be correct as per the SPI commands listed in the ENC28J60 datasheet.

Now just to check my SPI code, I tried to establish communication b/w two ATmega16A µC as per this tutorial. But instead of displaying the received value on an LCD, I used UART to send the values to my laptop. But I made the following observations:

  1. each time, the master shows a different received value even though the slave is sending a constant value of 0x11.
  2. Transmission and reception happens only when I take my hand near the circuit and stops as soon as my hand is removed.

I googled about this a lot and found that SPI is highly susceptible to EMI. I took the following measures to reduce errors due to EMI.

  1. I slowed down the SPI clock.
  2. I've put a 470µF capacitor across the Vcc and GND to eliminate noise from the power supply.
  3. I've reduced the wire length of MOSI,MISO and SCK.

What other measures can I take to get reliable and consistent communication over SPI?
And is my MAX232 IC causing a lot interference to my SPI signals?
And will using UART simultaneously with SPI affect the SPI reliability?

Best Answer

First you should figure out where the problem really is. The description of your setup is confusing, but it seems you are only looking at the SPI bus indirectly thru some firmware that reports things over a UART. There is a lot of opportunity for error in that. SPI busses that are short, on the same board, and above a ground plane pretty much just work. This is no different than other digital signals between chips on the same board. I sounds like you are chasing the wrong problem.

Look at the SPI clock and data lines with a scope. This lets you see what kind of noise there is, and also lets you verify short sequences are really what you think they are. I expect you'll find that you have a bug that is not causing what you think on the SPI bus, or not reporting correctly what is happening on the bus.

Keep in mind that the ENC28J60 has a fairly complicated SPI command set, including a segmented addressing scheme for some of its registers. Start with something simple, like writing some value to a particular register and verifying that you can read it back. Once you have that, it's good to create firmware layers for reading or writing any register, automatically tracking the bank and setting it as needed. Then create another layer for reading/writing PHY registers.

The good news is that the datasheet is well written and complete. I created a driver layer for the ENC28J60 for my TCP/IP stack just from the info in the datasheet.

Added

Another common cause of SPI flakiness is doing things on the wrong edge of the clock. Unfortunately there is no single standard. Look at the datasheet for the chip and the processor carefully to see on what edge of clock each is changing the data and when it is being read. Obviously you want to write on one edge and read on the other. If reading and writing is happening on the same clock edge, then flakiness where things change due to tiny capacitance changes are to be expected.

Again, look at the clock and data on a scope when a known byte is being sent.

Related Topic