Go Down

Topic: n00b SPI problem (Read 13 times) previous topic - next topic

zzpza

Jun 11, 2008, 10:48 pm Last Edit: Jun 11, 2008, 11:13 pm by zzpza Reason: 1
hello! :D

i have an arduino skinny (made by sparkfun) that i'm trying to get to talk to an scp1000 pressure sensor via spi. this is the first time i've tried to use the spi interface, and have to admit that i'm floundering a bit. here's the code i'm using:

Code: [Select]
// define spi bus pins
#define SLAVESELECT 10
#define SPICLOCK 13
#define DATAOUT 11      //MOSI
#define DATAIN 12       //MISO

//Addresses
#define REVID 0x00      //ASIC Revision Number
#define OPSTATUS 0x04   //Operation Status
#define STATUS 0x07     //ASIC Status

char lsb_in_byte;           //

void setup()
{
 byte clr;
 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(SLAVESELECT,OUTPUT);
 digitalWrite(SLAVESELECT,HIGH); //disable device  
 SPCR = B01010011; //MPIE=0, SPE=1 (on), DORD=0 (MSB first), MSTR=1 (master), CPOL=0 (clock idle when low), CPHA=0 (samples MOSI on rising edge), SPR1=0 & SPR0=0 (500kHz)
//  SPI2X=0; //No clock multiplier
 clr=SPSR;
 clr=SPDR;
 delay(10);
 Serial.begin(9600);                        // Connect to the serial port 9600 bps
 Serial.println("SCP1000 Code v0.01");
 delay(1000);
}

void loop()
{
 lsb_in_byte = read_register(REVID);
 Serial.print("REVID [");
 Serial.print(lsb_in_byte, HEX);
 Serial.println("]");
 lsb_in_byte = read_register(OPSTATUS);
 Serial.print("OPSTATUS [");
 Serial.print(lsb_in_byte, HEX);
 Serial.println("]");
 lsb_in_byte = read_register(STATUS);
 Serial.print("STATUS [");
 Serial.print(lsb_in_byte, HEX);
 Serial.println("]");
 delay(5000);  
}

char spi_transfer(volatile char data)
{
 SPDR = data;                    // Start the transmission
 while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
 {
 };
 return SPDR;                    // return the received byte
}

//Read 8-bit register
char read_register(char register_name)
{
   char in_byte;
   register_name |= 128; //Read command
   digitalWrite(SLAVESELECT,LOW); //Select SPI Device
   in_byte = spi_transfer(register_name); //Write byte to device
   //in_byte is nothing, we need to clock in another 8 bits
   in_byte = spi_transfer(0x00); //Send nothing, but we should get back the register value
   digitalWrite(SLAVESELECT,HIGH);
   return(in_byte);
}

//Sends a write command to SCP1000
void write_register(char register_name, char register_value)
{
   char in_byte;
   register_name &= 127; //Write command
   digitalWrite(SLAVESELECT,LOW); //Select SPI device
   in_byte = spi_transfer(register_name); //Send register location
   in_byte = spi_transfer(register_value); //Send value to record into register
   digitalWrite(SLAVESELECT,HIGH);
}


and here's the output i'm getting:

Code: [Select]
SCP1000 Code v0.01
REVID [0]
OPSTATUS [0]
STATUS [0]
REVID [0]
OPSTATUS [0]
STATUS [0]
REVID [0]
OPSTATUS [0]
STATUS [0]
REVID [0]
OPSTATUS [0]
STATUS [0]
REVID [0]
OPSTATUS [0]
STATUS [0]


no matter which register i read from, i just get zero. :( any help would very much be appreciated! :D

jules.

bens

I've only skimmed your code, but it looks like you're handling the SPI communication correctly.  Do you have access to an oscilloscope?  It would be helpful if you could see what your MOSI, MISO, and SCK lines look like.  Have you verified that you're using an SPI clock speed that your sensor can handle?  Is there anything in the datasheet about a required delay between when you send the register address and when you initiate the junk-byte transmission that will retrieve data from the sensor?

I made a post recently to help someone with an SPI problem here:

http://forum.pololu.com/viewtopic.php?f=1&t=986

My post links to some sample mega644 code for performing SPI communication, but this should be almost identical (if not exactly identical) to what you'd do on the mega168.

- Ben

Franklin

Here is the document from vti that I used to adapt the code to Propeller spin code.
Stephen

zzpza

Thank you bens and franklin! :)

It was a timing issue. I added a delay(10); after asserting the slaveselect and the data started to flow. :)

zlite

#4
Jul 28, 2008, 03:36 am Last Edit: Jul 28, 2008, 03:36 am by zlite Reason: 1
Quote
Thank you bens and franklin! :)

It was a timing issue. I added a delay(10); after asserting the slaveselect and the data started to flow. :)


Can you post the working code?

Go Up