您好!
我一直在尝试 通过 I2C 连接 ADXL345加速计。 我尝试过的所有方法 都导致我进入死区状态。无论我尝试传输的内容如何、都可以正常工作、但最后没有停止中断标志置位或 传感器无应答。 由于没有 ACK、我无法从传感器接收任何值。 我共享了我的整个代码。 仔细研究、让我知道您的建议。 提前感谢。
#include <msp430.h>
#include <stdio.h>
#include <stdint.h>
#define NUM_BYTES_TX 2
#define NUM_BYTES_RX 2
#define ADXL_345 0x53
int RXByteCtr, x1,y1,z1, RX_Data; // enables repeated start when 1
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[2];
uint8_t BW_RATE[2] ={0x2C,0x0D};
uint8_t POWER_CTL[2] ={0x2D,0x08};
uint8_t Data_Format[2] ={0x31,0x03};
unsigned int i,j;
void Setup_TX(unsigned char);
void Setup_RX(unsigned char);
void Transmit(unsigned char,unsigned char);
void TransmitOne(unsigned char);
void Receive(void);
void getX();
void getY();
void getZ();
void GPIO_Setup()
{
// Ports
P7SEL1 &= ~BIT0;
P7SEL0 |= BIT0;
P7SEL1 &= ~BIT1;
P7SEL0 |= BIT1;
// P7REN |= BIT0 | BIT1; // Enable Internal pullup resistor on P7.0 & P7.1
PM5CTL0 &= ~LOCKLPM5;
}
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
printf("Started Initialize\n");
//Transmit process
Setup_TX(ADXL_345);
TransmitOne(BW_RATE[0]);
while (UCB2CTL1 & UCTXSTP);
printf("0x2C\n");
Setup_TX(ADXL_345);
TransmitOne(BW_RATE[1]);
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
printf("0x0D\n");
Setup_TX(ADXL_345);
TransmitOne(POWER_CTL[0]);
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
printf("0x2D\n");
Setup_TX(ADXL_345);
TransmitOne(POWER_CTL[1]);
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
printf("0x08\n");
Setup_TX(ADXL_345);
TransmitOne(Data_Format[0]);
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
printf("0x31\n");
Setup_TX(ADXL_345);
TransmitOne(Data_Format[1]);
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
printf("0x03\n");
while(1)
{
getX();
// getY();
// getZ();
// printf("x1 = %d, y1 = %d, z1 = %d\n",x1,y1,z1);
}
}
void getX()
{
//Transmit process
Setup_TX(ADXL_345);
TransmitOne(0x32); // 0x32 // Request Data from ADXL345 in 2g Range 10Bit resolution
printf("Transmitted\n");
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
//Receive process
UCB2IFG &= ~UCSTPIFG;
Setup_RX(ADXL_345);
Receive();
}
void getY()
{
//Transmit process
Setup_TX(ADXL_345);
TransmitOne(0x34); // Request Data from ADXL345 in 2g Range 10Bit resolution
printf("Transmitted\n");
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
//Receive process
Setup_RX(ADXL_345);
Receive();
}
void getZ()
{
//Transmit process
Setup_TX(ADXL_345);
TransmitOne(0x36); // Request Data from ADXL345 in 2g Range 10Bit resolution
printf("Transmitted\n");
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
//Receive process
Setup_RX(ADXL_345);
Receive();
}
void Setup_TX(unsigned char Dev_ID){
RX = 0;
printf("Inside TX\n");
UCB2CTLW0 |= UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCCKPL;
UCB2CTLW0 |= UCSSEL__SMCLK; // Use SMCLK, keep SW reset
UCB2BRW = 10; // fSCL = SMCLK/12 = ~100kHz
UCB2CTLW0 |= UCMODE_3; // I2C Master, synchronous mode
UCB2CTLW0 |= UCMST;
UCB2CTLW0 |= UCTR;
UCB2I2CSA = Dev_ID; // Slave Address is 053h
UCB2CTLW1 = UCASTP_2; // automatic STOP assertion
GPIO_Setup();
UCB2CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB2IE |= UCTXIE0;
__enable_interrupt();
// __bis_SR_register(LPM0_bits + GIE);
}
void Setup_RX(unsigned char Dev_ID)
{
printf("Inside RX\n");
RX = 1;
UCB2CTLW0 |= UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCCKPL;
UCB2CTLW0 |= UCSSEL__SMCLK; // Use SMCLK, keep SW reset
UCB2BRW = 10; // fSCL = SMCLK/12 = ~100kHz
UCB2CTLW0 |= UCMODE_3; // I2C Master, synchronous mode
UCB2CTLW0 |= UCMST;
UCB2CTLW0 &=~UCTR;
UCB2I2CSA = Dev_ID; // Slave Address is 053h
UCB2CTLW1 = UCASTP_2; // automatic STOP assertion
UCB2TBCNT = 1;
GPIO_Setup();
UCB2CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB2IE |= UCRXIE0;
__enable_interrupt();
printf("RX Completed\n");
}
void Transmit(unsigned char Reg_ADD,unsigned char Reg_DAT)
{
__disable_interrupt();
printf("Inside Transmit Function\n");
MSData[1]= Reg_ADD;
MSData[0]= Reg_DAT;
UCB2TBCNT = NUM_BYTES_TX; // TX 2 bytes of data
TXByteCtr = NUM_BYTES_TX; // Load TX byte counter
while (UCB2CTL1 & UCTXSTP);
UCB2CTLW0 |= UCTXSTT; // I2C TX, start condition
__delay_cycles(2000);
__enable_interrupt();
}
void TransmitOne(unsigned char Reg_ADD)
{
printf("Inside TransmitOne Function\n");
TXByteCtr = 1;
UCB2TBCNT = 1;
MSData[0]= Reg_ADD;
UCB2CTLW0 |=UCTR;
UCB2CTLW0 |= UCTXSTT; // I2C TX, start condition
__delay_cycles(2000);
__enable_interrupt();
}
void Receive(void)
{
printf("Receive\n");
PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
RXByteCtr = 1;
while (UCB2CTL1 & UCTXSTP);
UCB2CTLW0 |= UCTXSTT; // I2C start condition
__delay_cycles(2000);
__enable_interrupt();
}
//-------------------------------------------------------------------
// ISR Vector
//-------------------------------------------------------------------
#pragma vector = EUSCI_B2_VECTOR
__interrupt void I2C_B2_ISR(void)
{
printf("Interrupt Routine\n");
switch(UCB2IV)
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
printf("inside NACK\n");
UCB2CTL1 |= UCTXSTT; //re-send start if NACK
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0
if(RX == 1)
{ // Master Receive?
RXByteCtr--; // Decrement RX byte counter
if (RXByteCtr)
{
*PRxData++ = UCB2RXBUF; // Move RX data to address PRxData
printf("Received = %d", *PRxData);
}
else
{
UCB2CTL1 |= UCTXSTP; // No Repeated Start: stop condition
*PRxData++ = UCB2RXBUF; // Move final RX data to PRxData
printf("Else Received = %d", *PRxData);
__disable_interrupt(); // Exit LPM0
}
}
else
{
printf("RX = 0\n");
}
break;
case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0
printf("ISR Transmitted\n");
UCB2TXBUF = MSData[0];
break;
case USCI_I2C_UCBCNTIFG: break; // Vector 26: BCNTIFG
case USCI_I2C_UCCLTOIFG: break; // Vector 28: clock low timeout
case USCI_I2C_UCBIT9IFG: break; // Vector 30: 9th bit
default: break;
}
}