Sign in

username or email:

password:



Not a member?
Forgot your Password?

Search msp430



Search tips

Subscribe to msp430



Discussion Groups

See Also

DSPFPGA

Discussion Groups | MSP430 | MSP430 I2C communication(2)

The purpose of this group is to foster exchange of information on the Texas Instruments MSP430 family of microcontrollers and related tools. Everyone welcome, all levels of familiarity/expertise.


So far in May, you have voted 0 times ou of a total of 20 votes by the community.
Please help us clean the archives from unuseful discussion threads by using the voting system! Details here.


Is this thread worth a thumbs up?

+2

MSP430 I2C communication(2) - Songsongsong - Aug 29 10:36:00 2012

Hi everyone, I should transmit and receive data from master(MSP430f5338) to slave sensor(LSM303DLM) by I2C communication.
I want to read data of x, y and z, so I can't receive multiple bytes because I have to change register continuously.
I made some codes using example codes from this group and TI example code. But there are two problems in my code.

First, the slave address register UCB0I2CSA is never changed from 0x48.
I assign the slave address 0x30 or the other hex numbers, but it was never changed from 0x48.

Second, in datasheet of this sensor, to write data, operation protocol is like below.
Master....Start.....SAD+W.....SUB.....DATA.....Stop
Slave.....................SAK.....SAK......SAK

And to read data, operation protocol is below.
Master....Start.....SAD+W.....SUB.....SR.....SAD+R...........Stop
Slave.....................SAK.....SAK..............SAK..DATA

So I programmed interrupt service routine like below, but RX interrupt service routine is never called.
Case 10: RXIFG routine in
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR (void)
is totally ignored and passed. I don't know why these problem is occured...
Here is my code. please help my problem.. I think the main problem part is function [DataRead] and interrupt service routine.
Thank you.

//////////////////////////////////////////////////////////////////
#include

unsigned char *PTxData;
unsigned char RXData;
unsigned char TXByteCtr = 1;

unsigned char ACC_Data[6], MAG_Data[6];
int ACC_X, ACC_Y, ACC_Z, MAG_X, MAG_Y, MAG_Z;

void SetAccMagPort (void)
{
P2SEL = 0; P2DIR = 0; P2OUT = 0; P2IES = 0; P2IE = 0;

P2SEL |= BIT1 | BIT2;

PMAPPWD = 0x2D52; // enable write access to any of the
// port mapping controller registers
if (!(PMAPCTL & PMAPLOCKED)) // if write access is granted
{
PMAPCTL |= PMAPRECFG;
P2MAP1 = PM_UCB0SDA; // P2.3 : UCB0CLK
P2MAP2 = PM_UCB0SCL; // P2.4 : UCB0SIMO
PMAPPWD = 0; // prevent further write accesses
}
else ;
}

void SetI2C (void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
UCB0CTL1 |= UCSWRST; // **Put state machine in reset**
UCB0CTL0 |= UCMST | UCSYNC | UCMODE_3;
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0BR0 = 0x04; // /4 --- 2.304 MHz
UCB0BR1 = 0;
UCB0I2CSA = 0x30;
UCB0CTL1 &= ~UCSWRST;
UCB0IE = UCTXIE;
//UCB0IE = UCRXIE;
}

void SetAccREG (void)
{
DataWrite(ACC_ADDRESS_W, CTRL_REG1_A, 0x27);
DataWrite(ACC_ADDRESS_W, CTRL_REG3_A, 0x40);
}
void DataWrite (unsigned char sadw, unsigned char sub, unsigned char data)
{
unsigned char temp[] = {sub, data};
PTxData = (unsigned char *)temp;
TXByteCtr = sizeof temp;

while(TXByteCtr)
{
UCB0I2CSA = sadw;
UCB0CTL1 |= UCTR | UCTXSTT;
__bis_SR_register(GIE);
__no_operation();
while(UCB0CTL1 & UCTXSTP);
}
}
unsigned char DataRead (unsigned char sadr, unsigned char sub)
{
UCB0IE &= ~UCRXIE;
UCB0IE |= UCTXIE;
UCB0I2CSA = ACC_ADDRESS_W;
PTxData = (unsigned char *)sub;
TXByteCtr = 1;
UCB0CTL1 |= UCTR | UCTXSTT;
__bis_SR_register(GIE);
while(UCB0CTL1 & UCTXSTP);

// UCB0CTL1 |= UCSWRST;
// UCB0CTL1 &= ~UCSWRST;
UCB0IE &= ~UCTXIE;
UCB0IE |= UCRXIE;
UCB0I2CSA = sadr;
//UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
__bis_SR_register(GIE);

return RXData;
}

void main (void)
{
SetAccMagPort();
SetI2C();
SetAccREG();

while(1)
{
ACC_Data[0] = DataRead(ACC_ADDRESS_R, OUT_X_L_A);
ACC_Data[1] = DataRead(ACC_ADDRESS_R, OUT_X_H_A);
ACC_Data[2] = DataRead(ACC_ADDRESS_R, OUT_Y_L_A);
ACC_Data[3] = DataRead(ACC_ADDRESS_R, OUT_Y_H_A);
ACC_Data[4] = DataRead(ACC_ADDRESS_R, OUT_Z_L_A);
ACC_Data[5] = DataRead(ACC_ADDRESS_R, OUT_Z_H_A);
ACC_X = (int)(ACC_Data[0] << 8) + ACC_Data[1];
ACC_Y = (int)(ACC_Data[2] << 8) + ACC_Data[3];
ACC_Z = (int)(ACC_Data[4] << 8) + ACC_Data[5];
}
}

#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR (void)
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG

case 10: // Vector 10: RXIFG

RXData = UCB0RXBUF; // Get RX data
UCB0CTL1 |= UCTXSTP;
break;

case 12: // Vector 12: TXIFG

if (TXByteCtr) // Check TX byte counter
{
UCB0TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
//__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
break;

default: break;
}
}





(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: MSP430 I2C communication(2) - Paul Curtis - Aug 29 10:49:53 2012

Hi,

> Hi everyone, I should transmit and receive data from master(MSP430f5338)
> to slave sensor(LSM303DLM) by I2C communication.
> I want to read data of x, y and z, so I can't receive multiple bytes
> because I have to change register continuously.

The 303DLM's accelerometer is intended to be read as a burst-mode
transaction with a repeated start, i.e. START+WRITE START+READ
NAK. The LSM303DLH device is the combination of a LIS331DL
and a Honeywell HMC5883L in a single integrated circuit and supports address
auto-increment through the accelerometer output registers. Read the
datasheet!

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore Development Platform http://www.soldercore.com





(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )