Hi,
I am using msp430f5529 and I have some communicate problem with the HMC5883L magnetometer via i2C. I had made a lot of tries but I can not read any data from it. I tried to write the next OPERATIONAL EXAMPLES that writen in the datasheet but it dosent work. I would like to hear ideas what is the problem in my code.
here is my code:
#include <msp430.h>
#include <msp430f5529.h>
#define NUM_BYTES_TX 3 // How many bytes?
#define NUM_BYTES_RX 6
#define HMC_5883 0x1E //address for write
int RXByteCtr, RPT_Flag = 0;
volatile unsigned char RxBuffer[6]; // Allocate 6 byte of RAM
unsigned char *PRxData; // Pointer to RX data
unsigned char TXByteCtr, RX = 0;
unsigned char MSData[4];
int magnetometer_data[3];
void Setup_TX(unsigned char);
void Setup_RX(unsigned char);
void Transmit(unsigned char,unsigned char,unsigned char);
void TransmitN(unsigned char,unsigned char);
void Receive(void);
int main(void)
{
int i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P4SEL |= BIT1 + BIT2; // Assign I2C pins to USCI_B1
P1DIR |=BIT5;
P1DIR |=BIT1;
P1OUT |=BIT5;
// Init sequence for hmc5883l
//Transmit process
Setup_TX(HMC_5883);
RPT_Flag = 1;
Transmit(0x3C,0x00,0x70);
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
Setup_TX(HMC_5883);
RPT_Flag = 1;
Transmit(0x3C,0x01,0xA0);
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
Setup_TX(HMC_5883);
RPT_Flag = 1;
Transmit(0x3C,0x02,0x00); // Request Data from HMC5883
Setup_RX(0x1E);
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
while(1){
//Transmit process
Setup_TX(HMC_5883);
RPT_Flag = 1;
TransmitN(0x3D,0x06); // Request Data from HMC5883
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
//Receive process
Setup_RX(0x1E);
Receive();
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
for ( i=0;i<3;i++)
{
magnetometer_data[i] = (int)RxBuffer[2*i + 1] + ((int)RxBuffer[2*i]<<8);
}
__delay_cycles(10000); // sample rate ~100 samples/sec
// you can change by changing delay
}
}
//-------------------------------------------------------------------------------
// The USCI_B0 data ISR is used to move received data from the I2C slave
// to the MSP430 memory. It is structured such that it can be used to receive
// any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
//-------------------------------------------------------------------------------
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
if(RX == 1){ // Master Recieve?
RXByteCtr--; // Decrement RX byte counter
if (RXByteCtr)
{
*PRxData++ = UCB1RXBUF; // Move RX data to address PRxData
}
else
{
if(RPT_Flag == 0)
UCB1CTL1 |= UCTXSTP; // No Repeated Start: stop condition
if(RPT_Flag == 1){ // if Repeated Start: do nothing
RPT_Flag = 0;
}
*PRxData = UCB1RXBUF; // Move final RX data to PRxData
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}}
else{ // Master Transmit
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = MSData[TXByteCtr]; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
if(RPT_Flag == 1){
RPT_Flag = 0;
TXByteCtr = NUM_BYTES_TX; // Load TX byte counter
__bic_SR_register_on_exit(CPUOFF);
}
else{
UCB1CTL1 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}
}
void Setup_TX(unsigned char Dev_ID){
_DINT();
RX = 0;
UCB1IE &= ~UCRXIE;
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent// Disable RX interrupt
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = Dev_ID; // Slave Address is 048h
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE; // Enable TX interrupt
}
void Setup_RX(unsigned char Dev_ID){
_DINT();
RX = 1;
UCB1IE &= ~UCTXIE;
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = Dev_ID; // Slave Address is 048h
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCRXIE; // Enable RX interrupt
}
void Transmit(unsigned char Reg_ADD,unsigned char Reg_DAT,unsigned char Reg_DAT2){
MSData[3]= Reg_ADD;
MSData[2]= Reg_DAT;
MSData[1]= Reg_DAT2;
TXByteCtr = NUM_BYTES_TX; // Load TX byte counter
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
void TransmitN(unsigned char Reg_ADD,unsigned char Reg_DAT){
MSData[2]= Reg_ADD;
MSData[1]= Reg_DAT;
//MSData[1]= Reg_DAT2;
TXByteCtr = 2; // Load TX byte counter
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
void Receive(void){
PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
RXByteCtr = NUM_BYTES_RX; // Load RX byte counter
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB1CTL1 |= UCTXSTT; // I2C start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}