使用MSP432G2553和HMC5883L进行I2C通信

时间:2018-04-09 20:36:45

标签: sensor i2c msp430

我正在尝试将我的HMC5883L磁力计与我的MSP432G2553连接,以便在x,y和z轴上获得连续读数,从而为设备提供方向。

我在使用i2c通信获取数据时遇到问题。我试图获取x,y和z数据,但我没有从我的代码中获取任何内容。我很感激任何反馈,我是I2C通信的新手。

我在网上找到了一个代码并且一直在使用它并对其进行修改。这是代码:

主要代码:

#include <msp430g2553.h>
#include "my_types.h"
#include "i2c.h"

#define M_PI   3.14159265358979323846264338327950288


int TXByteCtr;
unsigned char PRxData;
int Rx = 0;
char WHO_AM_I = 0x1E;

char itgAddress = 0x69;

const uchar setup_hmc5883[] = {0x00, 0x70};
const uchar gain_hmc5883[] = {0x01, 0xA0};
const uchar continuous_hmc5883[] = {0x02, 0x00};
const uchar base_hmc5883[] = {0x03};
char readBuffer [6];


void init_I2C(void);
void Transmit(void);
void Receive(void);


int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  int x, y, z ;
      float heading ;
      float headingDegrees ;
  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  BCSCTL1 = CALBC1_16MHZ ;
     DCOCTL = CALDCO_16MHZ ;
  init_I2C();



        Rx = 0;
        TXByteCtr = 1;
        writei2c(0x3C,setup_hmc5883,2);
        TXByteCtr = 1;
        writei2c(0x3C,gain_hmc5883,2);
        TXByteCtr = 1;
        writei2c(0x3C,continuous_hmc5883,2);

  while(1){
      writei2c(0x3C, base_hmc5883, 1);
                      __delay_cycles(100000);
                      readi2c(0X3D, readBuffer, 6);
                      x = readBuffer[0] ;
                      x |= readBuffer[1] << 8 ;
                      z = readBuffer[2] ;
                      z |= readBuffer[3] << 8 ;
                      y = readBuffer[4] ;
                      y |= readBuffer[5] << 8 ;
                      heading = atan2(y, x);
                      if(heading < 0) heading += 2*M_PI;
                      headingDegrees = heading * 180/M_PI;
  }
}

//-------------------------------------------------------------------------------
// 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
//-------------------------------------------------------------------------------
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  if(Rx == 1){                              // Master Recieve?
      PRxData = UCB0RXBUF;                       // Get RX data
      __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
  }

  else{                                     // Master Transmit
      if (TXByteCtr)                            // Check TX byte counter
        {
          if ((IFG2 & UCB0TXIFG) || (IFG2 & UCB0RXIFG))
          i2cDataInterruptService();
          TXByteCtr--;                            // Decrement TX byte counter
          if(!TXByteCtr)
                  {
                    UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
                    IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag
                    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
        }

 }

}
void init_I2C(void) {
      UCB0CTL1 |= UCSWRST;                      // Enable SW reset
      UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
      UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
      UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
      UCB0BR1 = 0;
      UCB0I2CSA = itgAddress;                         // Slave Address is 069h
      UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
      IE2 |= UCB0RXIE + UCB0TXIE;               //Enable RX and TX interrupt
}

i2c.c:

#include "i2c.h"

volatile char i2cBusy = 0;
volatile unsigned char i2cBufferLength = 0 ;
unsigned char * i2cBufferPtr ;
volatile char txDone = 1 ;
volatile char rxDone = 1 ;

void initi2c(unsigned int divider){

    P1SEL |= BIT6 + BIT7 ;
    P1SEL2 |= BIT6 + BIT7 ;
    UCB0CTL1 |= UCSWRST ;
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC ;
    UCB0CTL1 = UCSSEL_2 + UCSWRST ;
    UCB0BR0 = divider & 0x00FF ;
    UCB0BR1 = ((divider & 0xFF00) >> 8) ;
    UCB0I2CSA = 0x069 ;
    UCB0I2CIE = UCNACKIE | UCALIE;
    UCB0CTL1 &= ~UCSWRST ;
    IE2 |= UCB0TXIE | UCB0RXIE ;
}
char writei2c(unsigned char addr, unsigned char * data, unsigned char nbData){
    UCB0I2CSA = addr ;
    i2cBusy = 0 ;
    i2cBufferPtr = data ;
    i2cBufferLength = nbData ;
    txDone = 0 ;
    UCB0CTL1 |= UCTR + UCTXSTT;
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts

    //while(txDone == 0) ;
    //return txDone ;
}
char readi2c(unsigned char addr, unsigned char * data, unsigned char nbData){
    UCB0I2CSA = addr ;
    i2cBusy = 0 ;
    i2cBufferPtr = data ;
    i2cBufferLength = nbData ;
    rxDone = 0 ;
    UCB0CTL1 &= ~UCTR;
    UCB0CTL1 |= UCTXSTT;
    while(UCB0CTL1 & UCTXSTT);
    UCB0CTL1 |= UCTXSTP ;
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts



    while(rxDone == 0) ;
    return rxDone ;
}


inline void i2cDataInterruptService(void){
    if ((IFG2 & UCB0TXIFG) != 0 || (IFG2 & UCB0RXIFG) != 0){
        if((UCB0CTL1 & UCTR) != 0){
            if(i2cBusy >=  i2cBufferLength){
                UCB0CTL1 |= UCTXSTP ;
                i2cBusy = 0 ;
                txDone = 1 ;
                IFG2 &= ~UCB0TXIFG;
            }else{
                UCB0TXBUF = i2cBufferPtr[i2cBusy] ;
                i2cBusy ++ ;
            }
        }else{
            if((i2cBufferLength - i2cBusy) == 1){ // may generate a repeated stop condition
                UCB0CTL1 |= UCTXSTP ;
            }
            i2cBufferPtr[i2cBusy] = UCB0RXBUF;
            i2cBusy ++ ;
            if(i2cBusy >= i2cBufferLength){
                i2cBusy = 0 ;
                rxDone = 1 ;
            }
        }
    }
}

inline void i2cErrorInterruptService(void){
      if ((UCB0STAT & UCNACKIFG) != 0) {
        UCB0CTL1 |= UCTXSTP;
        UCB0STAT &= ~UCNACKIFG;
        i2cBusy = -1;
        txDone = -1 ;
        rxDone = -1 ;
    }else if ((UCB0STAT & UCALIE) != 0) {
                UCB0CTL1 |= UCTXSTP;
                UCB0STAT &= ~UCALIE;
                i2cBusy = -1;
        txDone = -1 ;
        rxDone = -1 ;
        }
}

0 个答案:

没有答案