我正在尝试将我的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 ;
}
}