SPI communication with ADIS gyro

General discussion on mikroC for dsPIC30/33 and PIC24.
Post Reply
Author
Message
dsPIC
Posts: 9
Joined: 04 Dec 2009 07:38
Location: NSW Australia

SPI communication with ADIS gyro

#1 Post by dsPIC » 13 Dec 2009 06:51

Hi I am trying to read the gyro rate out from one of these: http://www.analog.com/static/imported-f ... _16265.pdf
But my code is not working - it just ouputs 4626. I am using a dsPIC30F4011 with a 20Mhz crystal.

It uses 16-bit SPI and the address that I need to send to get the rotation rate is 0x0400. It will then send me back the rotation rate in a 14-bit number. I am using code that Sobrietytest posted which I slightly modifided for my part. I know that the gyro works because I have tested it on its evaluation board.

Here is the connection diagram:
Image

Currently my code outputs the int 4626 constantly over the serial port and the number doesnt change. The number should be changing with the rotation rate.
Here is my code:

Code: Select all

#include <Spi_Const.h>

const char CS_PIN = 0;                    // CS pin is RF0
int HiByte;
int LoByte;
int XGValue;
short buffer;
char txt[6];
int i = 0;


void InitMain() {
  ADPCFG = 0xFFFF;                        // Set AN pins as digital

  // Initialise SPI module
  Spi_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, _SPI_PRESCALE_SEC_5,
  _SPI_PRESCALE_PRI_4, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_END,
  _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);

  TRISF.CS_PIN = 0;                       // Set CS pin as output
  PORTF.CS_PIN = 1;                       // Set CS high

  Uart2_Init(9600);                        // Initialise UART module

}


void readADIS() {

  PORTF.CS_PIN = 0;                       // Select DAC module
  Spi_Write(0x04);                        // Send data via SPI
  Spi_Write(0x00);                        // Send data via SPI
  PORTF.CS_PIN = 1;                       // Deselect DAC module
  
  Delay_us(15);                           // Stall period between data
  
  PORTF.CS_PIN = 0;                       // Select DAC module
  HiByte = Spi_Read(buffer);              // Read the MSByte
  LoByte = Spi_Read(buffer);              // Read the LSByte
  PORTF.CS_PIN = 1;                       // Deselect DAC module
  
  HiByte = (HiByte <<8);                  // Bitshift the MSByte 8 places left
  XGValue = HiByte + LoByte;              //then add them together
  XGValue = (XGValue & 0b0011111111111111); //Strip off the ND and EA flags

}


void main() {
  InitMain();

  while (1) {                             // Main loop
    readADIS();
    
    WordToStr(XGValue, txt);              // Convert XGValue to array of numbers
    for (i=0; i<6; i++)                   // Display XGValue on serial
    Uart2_Write_Char(txt[i]);
    Uart2_Write_Char('\n');               // new line

    Delay_ms(300);                        // Update rate

  }
}
Can anyone see why the code is not working?

Thanks

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

#2 Post by Sobrietytest » 14 Dec 2009 05:16

The most obvious error that I can see here is your implementation of 16-bit SPI, in this case TWO bytes are sent and received, Therefore your address send and data read can be done in one pass...

Code: Select all

void readADIS() { 

  PORTF.CS_PIN = 0;                       // Select DAC module 
  Spi_Write(0x0400);                       // SEND 2 BYTE ADDRESS
  //Spi_Write(0x00);                        // YOU DON'T NEED THIS
  PORTF.CS_PIN = 1;                       // Deselect DAC module 
  
  Delay_us(15);                           // Stall period between data 
  
  PORTF.CS_PIN = 0;                       // Select DAC module 
  XGValue = Spi_Read(buffer);          // READ 16-BIT DATA
  //LoByte = Spi_Read(buffer);          // YOU DON'T NEED THIS
  PORTF.CS_PIN = 1;                       // Deselect DAC module 
  
  //HiByte = (HiByte <<8);                  // YOU DON'T NEED THIS 
  //XGValue = HiByte + LoByte;           //YOU DON'T NEED THIS
  XGValue = (XGValue & 0b0011111111111111); //Strip off the ND and EA flags 

} 


void main() { 
  InitMain(); 

  while (1) {                             // Main loop 
    readADIS(); 
    
    WordToStr(XGValue, txt);              // Convert XGValue to array of numbers 
    for (i=0; i<6; i++)                   // Display XGValue on serial 
    Uart2_Write_Char(txt[i]); 
    Uart2_Write_Char('\n');               // new line 

    Delay_ms(300);                        // Update rate 

  } 
}
I haven't tested it but try it and see what happens.

dsPIC
Posts: 9
Joined: 04 Dec 2009 07:38
Location: NSW Australia

#3 Post by dsPIC » 14 Dec 2009 05:46

Hi, This fixed it!
I changed _SPI_16_BIT to _SPI_8_BIT and _SPI_DATA_SAMPLE_MIDDLE and leaved the code the same and it now works. I will modify the code the way you have for neatness.

Code: Select all

  // Initialise SPI module
  Spi_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1,
  _SPI_PRESCALE_PRI_16, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE,
  _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);
Thankyou very much.

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

#4 Post by Sobrietytest » 14 Dec 2009 18:32

NFP, get to it! I'm sorry if the 8-bit solution caused confusion. Good luck with your project.

Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

#5 Post by Mince-n-Tatties » 16 Dec 2009 22:54

dsPIC wrote:Hi, This fixed it!
I changed _SPI_16_BIT to _SPI_8_BIT and _SPI_DATA_SAMPLE_MIDDLE and leaved the code the same and it now works. I will modify the code the way you have for neatness.

Code: Select all

  // Initialise SPI module
  Spi_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1,
  _SPI_PRESCALE_PRI_16, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE,
  _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);
changed _SPI_16_BIT to _SPI_8_BIT

if you look at what ST was adding a few answers above, it was to say that you have a PIC which has a 16 bit SPI module and you have a 16 bit SPI gyro, so instead of using the 2 x 8 bit software method (which is typically how we get around using 8 bit SPI pics while connectd to > 8 bit external devices) you should stick with working in 16 bit as supported by both devices.

its also likely that changed _SPI_DATA_SAMPLE_MIDDLE is a better timing fit for your device, so stick with that change unless you have a scope to confirm timings.

working in 16 bit will reduce code greatly in this case. and remove the need for external "built-in" functions

dsPIC
Posts: 9
Joined: 04 Dec 2009 07:38
Location: NSW Australia

#6 Post by dsPIC » 19 Dec 2009 04:25

Yes, I'll perform some code compacting like you say.
Cheers

Post Reply

Return to “mikroC for dsPIC30/33 and PIC24 General”