MC9S12C32 to drive MMA7455L freescale accelerometer

cancel
Showing results for 
Search instead for 
Did you mean: 

MC9S12C32 to drive MMA7455L freescale accelerometer

1,978 Views
Ersancan
Contributor I

Hello. im trying to drive mma7455l accelerometer with a csm12c32 dev. board( has mc9s12c32 micrprocessor on it). i couldnt manage to use spi module somehow. and now im trying to use gpio pins to communicate with accelerometer. i have another problem now. i cannot write a r/w register of accelerometer but i can read register values. here is my source code to communicate through gpio pins:

 

 

 

#include <hidef.h>      /* common defines and macros */#include <mc9s12c32.h>     /* derivative information */#pragma LINK_INFO DERIVATIVE "mc9s12c32"#define CS_HIGH     ( PTT = PTT | 0x01) //|0000|0001| #define CS_LOW      ( PTT = PTT & 0xFE) //|1111|1110|#define SCL_HIGH    ( PTT = PTT | 0x02) //|0000|0010|#define SCL_LOW     ( PTT = PTT & 0xFD) //|1111|1101|#define SDO_HIGH    ( PTT = PTT | 0x04) //|0000|0100|#define SDO_LOW     ( PTT = PTT & 0xFB) //|1111|1011|unsigned char val=0;void main(void);void initSPI(void);void Delay10TCY();void Delay10KTCYx(int i);unsigned char ReadSPI(unsigned char address);void WriteSPI(unsigned char address, unsigned char data);unsigned char SPI_RByte(void);void SPI_WByte(unsigned char data);  void main(void) {    EnableInterrupts;      DDRA = 0x01;    DDRB = 0x10;    PORTA = 0x01;    PORTB = 0x10;    initSPI();         for(;;){     val=0; // reset value        PORTA = 0x01; // turn LED OFF             //Set up MMA7455L operation mode by writing to hex addr 16, hex value 05 (2g, 4 wires)     WriteSPI(0x16,0x05);     Delay10KTCYx(100);     val = ReadSPI(0x16);// read value back from register and if expected value turn ON the LED          if(val==0x05){         PORTA = 0x00;     }// turn LED ON     /*     else{         PORTA = 0x01;     }// turn LED OFF        */             Delay10KTCYx(100);               if(PORTB == 0x00)         PORTB = 0x10;     else         PORTB = 0x00;     }}void initSPI(void){ DDRT = 0x07; //|0000|0111| CS_HIGH; SDO_LOW; SCL_LOW;}void Delay10TCY(){ int x; for(x=0;x<255;x++){}}void Delay10KTCYx(int i){ int x; for(x=0;x<i;x++){  Delay10TCY(); }   }void SPI_WByte(unsigned char data){ char x; for(x=0;x<8;x++){ //Loop 8 bits  SCL_LOW; //Clock Low  Delay10TCY();  SDO_LOW;  if((data & 0x80) > 0)//Clear entire byte except bit 7 and check if byte is greater than 0   SDO_HIGH; //Set the Data Out to HIGH    Delay10TCY(); //Delay 5uS  SCL_HIGH; //Clock High  Delay10TCY(); //Delay 5uS  data <<= 1; //Shift data bit out to the right } Delay10TCY(); //Delay 5uS}unsigned char SPI_RByte(void){ char x,data; for(x=0;x<8;x++){ //Loop 8 bits  SCL_LOW; //Clock Low  Delay10TCY(); //5uS delay  data <<= 1; //Shift 1 bit to the left  data &= 0xFE; //Clear BIT 0 from byte without touching the rest  if( (PTT & 0x08) > 0) //if the Serial Data In is HIGH do below if not then leave it 0   data |= 1; //OR in a 1 into out byte  SCL_HIGH; //Clock High  Delay10TCY(); //5uS delay } Delay10TCY(); //Delay 5uS return data; //return our data}void WriteSPI(unsigned char address, unsigned char data){ SCL_HIGH; //Clock High CS_LOW; //Chip Select Low address = ( ( ( address << 1 ) & 0x7F ) | 0x80 );  SPI_WByte(address); //Write our address SPI_WByte(data); //Write our data CS_HIGH; //Chip Select High}unsigned char ReadSPI(unsigned char address){ unsigned char tmp; SCL_HIGH; //Clock High CS_LOW; //Chip Select Low address=( ( address << 1 ) & 0x7f );//Send read command together with reg address SPI_WByte(address); //Write our address to read from tmp = SPI_RByte(); //Get the byte from the device CS_HIGH; //Chip Select High return tmp; //Return tmp}

 

 

 

is there any thing wrong with src? i need a help very badly.

 

ps: if anyone has a tested & working source code using spi module to share, that would be great too.

 

Have a good day

 

Message Edited by Ersancan on 2010-01-02 05:17 PM
Message Edited by Ersancan on 2010-01-02 05:29 PM
Labels (1)
0 Kudos
6 Replies

235 Views
Ersancan
Contributor I
  by the way, i forgot to mention how i am sure about i can read registers. there is a register that keeps i2c address of the accelerometer. register address is 0x0D and value is 0x1D. i switch on a led if i read 1D value from 0D address. 
Message Edited by Ersancan on 2010-01-02 11:47 PM
0 Kudos

235 Views
ipa
Contributor III

Hi,

In this line:

if( (PTT & 0x08) > 0) //if the Serial Data

 use PTIT - the input port register. PTT read returns the status

of this register as output.

Regards,

ipa 

0 Kudos

235 Views
Ersancan
Contributor I

thanks for reply. but i couldnt see if this makes a difference. forgive me if i become blind by looking at the same code for over one week.

anyways i replaced PTT with PTIT and nothing changed. register read operation already works fine.

0 Kudos

235 Views
kef
Specialist I

Ersancan,

 

I looked into MMA7455 datasheet and it seems your code doesn't agree with SPI timing diagrams. At least clock polarity is reversed. Clock should idle low, while in your code I see it idling high. You initiate write transfer setting clock high, then setting CS low. But CS bit is not only SPI slave select, it also switches MMA chip from/to IIC and SPI modes. I think you should make clock idling low, so that when you set CS low, clock is also low. Then you also will need to modify SPI_Write and SPI_Read routines. in SPI_Write you should first set up MMA SDI line, then pulse clock high then low. Read seems to be the similar: sample MMA SDO pin, then pulse clock high then low. Or maybe set clock high, sample SDO, then set clock low.

 

0 Kudos

235 Views
Lundin
Senior Contributor IV
In my experience, 95% of all SPI problems are indeed solved by RTFM :smileyhappy:

There is no SPI standard as such, silicon manufacturers implement SPI (or whatever they choose to call it) in a completely arbitrary manner.
Message Edited by Lundin on 2010-01-05 11:36 AM
0 Kudos

235 Views
ipa
Contributor III

 

Hi,

Look for AN3468 and the correspoding software package - there is already

a software example.

Regards,

ipa

0 Kudos