Hi there!
It's been a while since I bugged you people with a question and now I have another one. It relates to SPI communication. I am trying to read values from a Freescale accelerometer (MMA7455L) using a PIC 18F4550 and SPI.
To that end, I wrote some simple code. Now, it doesn't seems to work as the program seems stuck when trying to read the value I just wrote into a register of the MMA7455L. What I would like you to do is take a look at my code and tell me if you think it's valid. If you think it's Ok then I can start thinking about bugging the Freescale people. Many thanks!
- Florian
Edit - just to add a few details. Because MMA7455L operates in slave mode, I am using bit 6 on PORTD to toggle SPI transmission. Also, the write command seems to work as when I am debugging it exits the loop, however the code gets stuck when trying to read the value written into the register (testing to see if the code works).
The clock is FOSC/4, so about 5MHz as I am using a 20MHz crystal (that speed is Ok for the MMA7455L if the VDD is > 2.4 and it is in my case).
It's been a while since I bugged you people with a question and now I have another one. It relates to SPI communication. I am trying to read values from a Freescale accelerometer (MMA7455L) using a PIC 18F4550 and SPI.
To that end, I wrote some simple code. Now, it doesn't seems to work as the program seems stuck when trying to read the value I just wrote into a register of the MMA7455L. What I would like you to do is take a look at my code and tell me if you think it's valid. If you think it's Ok then I can start thinking about bugging the Freescale people. Many thanks!
- Florian
Edit - just to add a few details. Because MMA7455L operates in slave mode, I am using bit 6 on PORTD to toggle SPI transmission. Also, the write command seems to work as when I am debugging it exits the loop, however the code gets stuck when trying to read the value written into the register (testing to see if the code works).
The clock is FOSC/4, so about 5MHz as I am using a 20MHz crystal (that speed is Ok for the MMA7455L if the VDD is > 2.4 and it is in my case).
Code:
#include <p18f4550.h>
#include <delays.h>
#pragma config WDT = OFF, FOSC = INTOSC_HS, LVP=OFF
unsigned char val=0;
void picdelay (unsigned char n);
void ledonoff ();
unsigned char spi_r(unsigned char reg);
void spi_w(unsigned char regaddr, unsigned char regdata);
void main (void)
{
// Make all bits on the Port D (LEDs) output bits.
TRISD = 0;
//initializing SPI operation
SSPSTAT=0xC0; //11xxxxxx (x = don't care)
SSPCON1=0x30; //0011xxxx (x = don't care)
//Enable I/O
//SDO must have TRISC<7> bit cleared
TRISCbits.TRISC7=0;
//SCK must have TRISB<1> bit cleared.
TRISBbits.TRISB1=0;
//Set up MMA7455L operation mode by writing to hex addr 16, hex value 05 (2g, 4 wires)
spi_w(22,5); // 22 = 0x16, 5 = 0x05
while (1) {
val = spi_r(22); // read value back from register and if expected value flash the LED
if(val==5){ledonoff();}
};
}// End of the main program
//SPI write command function reg - 1rrrrrrx (bit 7 is 1, next 6 bits reg address and a don't care)
void spi_w(unsigned char regaddr, unsigned char regdata)
{
unsigned char tmp;
PORTDbits.RD6 = 0; // pull the CS low to start SPI transmission
SSPBUF=(((regaddr&0x3F)<<1)|0x80); // send register address to the accelerometer with write command
while(!SSPSTATbits.BF);// wait for transfer
tmp=SSPBUF; // reading SSPBUF clears the BF bit
SSPBUF=regdata; // send data into the accelerometer register
while(!SSPSTATbits.BF);
tmp=SSPBUF; // reading SSPBUF clears the BF bit
PORTDbits.RD6 = 1; // pull the CS high to stop SPI transmission
}
//SPI read function (send read register commands to the accelerometer and output resultant read byte)
unsigned char spi_r(unsigned char reg)
{
unsigned char temp;
PORTDbits.RD6 = 0; // pull the CS low to start transmission
SSPBUF=((reg&0x3F)<<1); // // send register affress to the accelerometer with read command
while(!SSPSTATbits.BF);// wait for transmit to finish
temp=SSPBUF; // reading SSPBUF clears the BF bit
while(!SSPSTATbits.BF); // wait for receive to finish
temp=SSPBUF; // reading SSPBUF clears the BF bit
PORTDbits.RD6 = 1; // pull the CS high to stop transmission
return temp;
}
Last edited: