SPI Help!
Topic last updated
11 Feb 2010, by
Martin Smith.
3 replies
Encoder,
SPI
Hi all,
I'm trying to get an encoder to work over SPI. I had prevoiusly got it going by bit-bashing it, but am told that SPI would be better. The Encoder is the AS5045 and my bit-bashing code was...
EncoderValue=0;
ChipSelect=0; //Send Chip Select low to start read
wait_us(1); //Wait 1 microsecond
Clock=0; //Send Clock low
for(int i=1;i<18;i++){
wait_us(1); //Wait 1 microsecond
Clock=1; //Set clock high to start bit read
wait_us(1); //Wait 1 microsecond for data to latch onto bus
if(Data)
EncoderValue++; //If the bit is high add 1 to the encoder value
EncoderValue=EncoderValue*2; //Bitshift EncoderValue once
wait_us(1); //Wait 1 microsecond (This line may not be needed)
Clock=0;
}
Encoder=EncoderValue>>6;
ChipSelect=1; //Send Chip Select high to stop read
pc.printf("Position %u \r",Encoder);
The first problem I ran into was the encoder returns 18 bits (12 data & 6 status), but SPI only deals with 16 max. So i thought I would read it twice?
My code is...
spi.format(9,2); // Setup the spi for 9 bit data, high steady state clock,
spi.frequency(500000);
cs = 0; // Select the device by seting chip select low
// Send a dummy byte to receive the contents encoder
int upper = spi.write(0x00);
int lower = spi.write(0x00);
lower = lower >> 6;
upper = (upper << 6)+lower;
cs = 1;
pc.printf("%d \r", upper);
which is quite a bit shorter but doesn't work!
Can anyone help me with this. It's my first try with SPI and i'm getting in a bit of a muddle.
Thanks
Martin
Replies
#
11 Feb 2010 . Edited: 11 Feb 2010
1) You need to use spi.read(), not spi.write().
2) It seems the device uses "data are read on the clock's falling edge and data are changed on a rising edge", i.e. POL=0 and PHA=1, so you probably should try mode 1.
3) To extract the data from two 9-bit reads, I think you need to use the following expression: data = (upper<<3) | (lower >>6)
4) You could also try reading just 12 bits and discard the status ones by raising the CS. Whether that works for multiple measurements depends on the device.
Thanks for your quick reply Igor. Can you explain about the POL & PHA, I can't find an account of them in the handbook except to say what the truth table for the mode is.
Thanks
Martin
There is explanation in Wikipedia. See also the timing diagrams.
Please log in to post a reply.
Hi all,
I'm trying to get an encoder to work over SPI. I had prevoiusly got it going by bit-bashing it, but am told that SPI would be better. The Encoder is the AS5045 and my bit-bashing code was...
EncoderValue=0;
ChipSelect=0; //Send Chip Select low to start read
wait_us(1); //Wait 1 microsecond
Clock=0; //Send Clock low
for(int i=1;i<18;i++){
wait_us(1); //Wait 1 microsecond
Clock=1; //Set clock high to start bit read
wait_us(1); //Wait 1 microsecond for data to latch onto bus
if(Data)
EncoderValue++; //If the bit is high add 1 to the encoder value
EncoderValue=EncoderValue*2; //Bitshift EncoderValue once
wait_us(1); //Wait 1 microsecond (This line may not be needed)
Clock=0;
}
Encoder=EncoderValue>>6;
ChipSelect=1; //Send Chip Select high to stop read
pc.printf("Position %u \r",Encoder);
The first problem I ran into was the encoder returns 18 bits (12 data & 6 status), but SPI only deals with 16 max. So i thought I would read it twice?
My code is...
spi.format(9,2); // Setup the spi for 9 bit data, high steady state clock,
spi.frequency(500000);
cs = 0; // Select the device by seting chip select low
// Send a dummy byte to receive the contents encoder
int upper = spi.write(0x00);
int lower = spi.write(0x00);
lower = lower >> 6;
upper = (upper << 6)+lower;
cs = 1;
pc.printf("%d \r", upper);
which is quite a bit shorter but doesn't work!
Can anyone help me with this. It's my first try with SPI and i'm getting in a bit of a muddle.
Thanks
Martin