Go Down

Topic: SPI clock troubles... ?? (Read 1 time) previous topic - next topic

jrwalker

Hi. We are working with the Arduino Mini for a school project and cannot seem to get SPI working. We are trying to pull sensor data from a 3 axis accelerometer and can't get it to work. We tried to set up a simple program that simply shows us the output of SCK, but cannot get it to work I have one main question:

Is there a function to call in order to start the SPI clock (SCK)? We have tried to read the SPI clock (pin 13 as per the arduino SPI help) with the arduino mini, but cannot seem to get a clock signal from it; we only get zero's. The arduino reference says that SPI.begin() pulls SCK low, which would make sense since we are getting only zero's. Is there something else we need to do to initialize SCK? Below is the code:



#include <SPI.h>
unsigned int x=0;

void setup () {
 
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPI.begin();
 
}

void loop () {
 

  Serial.begin(9600);
  pinMode(7, INPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  x = digitalRead(7);
  Serial.print("x=");
  Serial.print(x);
  Serial.print('\n');
  delay(0.001);
  digitalWrite(8, LOW);
  delay(0.001);
 
}


We have SCK (pin 13) hooked directly to pin 7 so that we can read the clock, but like I said, we get nothing but zero's. Any help is appreciated!!

CrossRoads

I'm pretty sure you just get a burst of clock pulses with the command
SPI.transfer(value);

SPI.begin is like Serial.begin - nothing actually goes on until you command a read or a write.
The Dataout will come out of the MOSI pin and be read back on the MISO pin. The same burst of clock does both I believe (I have only written out).

http://www.arduino.cc/playground/Code/Spi

here's an example of data going out:
Code: [Select]

  number_to_display = number_to_display | colon; // OR in the decimal point
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip
  SPI.transfer(minutes_tens_address);  // select the Address,
  SPI.transfer(number_to_display);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Graynomad

Crossroads is right re the burst of pulses, just 8 ber byte then nothing until the next byte.

Why is this

Code: [Select]
Serial.begin(9600);
 pinMode(7, INPUT);
 pinMode(8, OUTPUT);


In loop(), it should be in setup();

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Nick Gammon


Is there a function to call in order to start the SPI clock (SCK)? We have tried to read the SPI clock (pin 13 as per the arduino SPI help) with the arduino mini, but cannot seem to get a clock signal from it; we only get zero's.


You don't "start the clock". Take a look at the logic analyzer output on my web page here:

http://www.gammon.com.au/forum/?id=10892

The clock line is normally zero, except during SPI.transfer, and then it only goes high very briefly (like, 3 microseconds).

I don't see an SPI.transfer in your code, so I wouldn't expect much to happen. Also you may need to pull SS low for the device before it does anything.

CrossRoads

That's  a great writeup on SPI Nick.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Nick Gammon


jrwalker

Thanks all for the info. This is our first time using SPI and we are still trying to debug things and get everything talking.

Nick, that is a GREAT logic analyzer output. I was considering doing this as well to try and figure out SPI. Looks like you've already answered all the questions I would have about SPI with your logic analyzer output :).

Gray, I wasn't sure if pinMode(...) and Serial.begin(...) were global functions if we called them inside void setup ().

I will try to change a few things in my code in order to take these new insights into consideration and let everyone know how it goes.

Best,
Jimmy

jrwalker

Another quick question:

From the SPI.begin() help on the arduino website:

"Description
Initializes the SPI bus, setting SCK, MOSI, and SS to outputs, pulling SCK and MOSI low and SS high."

What if you have a chip that needs SS low to select the chip? Does "pulling SCK low" mean it pulls SCK low no matter what the SPI data mode is set to? Also, does SPI.begin() set MISO to an INPUT? This seems a little unclear to me from the arduino help. I'm still playing around with it trying to get some expected communication between the arduino and the slave, but still no avail. Thanks.

Best,
Jimmy

Nick Gammon

This is the code from SPI.cpp:

Code: [Select]
void SPIClass::begin() {
  // Set direction register for SCK and MOSI pin.
  // MISO pin automatically overrides to INPUT.
  // When the SS pin is set as OUTPUT, it can be used as
  // a general purpose output port (it doesn't influence
  // SPI operations).

  pinMode(SCK, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(SS, OUTPUT);
 
  digitalWrite(SCK, LOW);
  digitalWrite(MOSI, LOW);
  digitalWrite(SS, HIGH);

  // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  // automatically switches to Slave, so the data direction of
  // the SS pin MUST be kept as OUTPUT.
  SPCR |= _BV(MSTR);
  SPCR |= _BV(SPE);
}


Note that it doesn't directly set MISO to an input, but the documentation for the Atmega says "When the SPI is enabled, the data direction of the MOSI, MISO, SCK, and SS pins is overridden according to Table 18-1 on page 168.". And that table says the MISO is set as an input. So the enabling of SPI does indeed set MISO as an input. The other ones are done in SPI.begin because the chip itself doesn't want to set things to an output in case you didn't really want to do that.

Quote
What if you have a chip that needs SS low to select the chip?


Well that is the normal case, and you can see that it sets SS as an output, and initially high. So you set it low when you want to write to it, and then high again (as in my example).

Quote
Does "pulling SCK low" mean it pulls SCK low no matter what the SPI data mode is set to?


Well the code certainly does, however my tests reveal that if you do this:

Code: [Select]
  SPI.begin ();
  SPI.setDataMode (SPI_MODE2);  // clock is high to low


Then the SPI hardware switches the clock to normally high, so you don't have to worry about that.

djc


...cannot seem to get SPI working.


What version of the IDE are you using? In versions previous to 0022, there was a bug in the code.

CrossRoads

What SPI bug is in versions prior to 0022?
I have been using 0021 with a MAX7221 without modifications (just call spi.begin and then SS low, spi.transer,SS high) and have not seen any odd behavior.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.


Go Up