Is something wrong with my SPI? - Page 1
Forum section: electronics / beginners

author: tribble222
author_rank: Newbie
timestamp: July 23, 2016, 05:57:44 am
content: I have an atmega328p talking to a LIS3DH accelerometer. I hooked it up to my scope to check out what SPI looks like since I haven't seen it before. I noticed that there's quite a bit of jitter in there. The SCL is what you're looking at here. I don't believe it's a triggering issue. The first 4 sections seem to be pretty consistent, but the last 4 jitter around...I've attached some stills and here's a link to a gif:https://gfycat.com/VibrantLightCurassowIs this normal or is there something wrong with my setup?Edit: it seems to be about 8us of jitter

author: Signal32
author_rank: Frequent Contributor
timestamp: July 23, 2016, 06:14:29 am
content: It is normal.What you are seeing can't really be called jitter.The delays that you are seeing are because the code that you are running on the micro is non-deterministic(2nd time around it executes more instructions, causing the "delay" that you are seeing).Post the code that executes to generate the trace that we are seeing.Perhaps an interrupt is being triggered, perhaps you have an if/else statement in there somewhere, etc

author: tribble222
author_rank: Newbie
timestamp: July 23, 2016, 03:51:10 pm
content: I'm using theAdafruit LIS3DH library. I'm just running a loop that callsCode:lis.read();over and over. I snipped out what appears to be the relevant part of the library:Code:void Adafruit_LIS3DH::read(void) {// read x y z at onceSPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));digitalWrite(_cs, LOW);spixfer(LIS3DH_REG_OUT_X_L | 0x80 | 0x40); // read multiple, bit 7&6 highx = spixfer(); x |= ((uint16_t)spixfer()) << 8;y = spixfer(); y |= ((uint16_t)spixfer()) << 8;z = spixfer(); z |= ((uint16_t)spixfer()) << 8;digitalWrite(_cs, HIGH);if (_sck == -1)SPI.endTransaction(); // release the SPI bus}#endifuint8_t range = getRange();uint16_t divider = 1;if (range == LIS3DH_RANGE_16_G) divider = 1365; // different sensitivity at 16gif (range == LIS3DH_RANGE_8_G) divider = 4096;if (range == LIS3DH_RANGE_4_G) divider = 8190;if (range == LIS3DH_RANGE_2_G) divider = 16380;x_g = (float)x / divider;y_g = (float)y / divider;z_g = (float)z / divider;}I attached a picture of all 4 SPI lines at once.yellow = CLKcyan = MOSIpink = CSblue = MISO

author: Signal32
author_rank: Frequent Contributor
timestamp: July 23, 2016, 04:30:42 pm
content: Quote from: tribble222 on July 23, 2016, 03:51:10 pmThe read() function reads 7 words, these 7 appear as not having any "jitter" in your trace.When the large gap happens, you can see the CS go high/low.This means it's exiting and re-entering the read() function. And therefore doing all the begin/end transaction stuff and toggling CS low/high. Also anything else you might have in your loop.So yes, it is expected that executing that code generate the delay / gap that is there.

author: tribble222
author_rank: Newbie
timestamp: July 24, 2016, 12:03:33 am
content: Thanks for the insight. I think I've figured it out.First, the master sends a command to read 6 pieces of data containing the accelerations on 3 axis from the slave. Those are the first 7 clock bursts (1 command & 6 reads). Then the SPI bus is closed (CS goes high). Then it is re-opened (CS goes low again) and master asks for 1 more piece of data, what the current acceleration range is set to, then it closes the bus again. Those are the last 2 pulses.Some math is done to the data in between these, and the data is always changing, so I think that's why the pulses aren't always perfectly in sync.Basically what you were saying. Thanks a lot