本帖最后由 eelpy 于 2019-6-11 14:57 编辑
id一直可以读, 但是加速度的却一直为0。 昨晚用一样的程序可以读出加速度数据,但是今天又不行了,一只是0. 能读id说明线路没问题吧?
#include "ADXL362.h" // ADXL362 definitions.
#include "msp430.h"
#include "Communication.h"
/******************************************************************************/
/************************ Variables Definitions *******************************/
/******************************************************************************/
unsigned char status = 0;
short xAxis = 0;
short yAxis = 0;
short zAxis = 0;
//float temperature = 0;
/***************************************************************************//**
* @brief Draws the ADI logo and displays the name of ADI component.
*
* @param componentName - The name of the ADI component.
*
* @return None.
*******************************************************************************/
/***************************************************************************//**
* @brief Main function.
*
* @return None.
*******************************************************************************/
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
/* Init device. */
ADXL362_Init();
/* Put the device in standby mode. */
/* Put the device in standby mode. */
ADXL362_SetPowerMode(0);
/* Set accelerometer's output data rate to: 12.5 Hz. */
ADXL362_SetOutputRate(ADXL362_ODR_12_5_HZ);
/* Setup the activity and inactivity detection. */
ADXL362_SetRegisterValue(
ADXL362_ACT_INACT_CTL_LINKLOOP(ADXL362_MODE_LINK),
ADXL362_REG_ACT_INACT_CTL,
1);
ADXL362_SetupActivityDetection(1, 30, 1);
ADXL362_SetupInactivityDetection(1, 700, 25);
/* Start the measurement process. */
ADXL362_SetPowerMode(1);
/* Clear ACT and INACT bits by reading the Status Register. */
ADXL362_GetRegisterValue(&status,ADXL362_REG_STATUS,1);
while(1)
{
do
{
ADXL362_GetRegisterValue(&status, ADXL362_REG_STATUS, 1);
}while(
((status & ADXL362_STATUS_DATA_RDY) == 0) &&
((status & ADXL362_STATUS_INACT) == 0) &&
((status & ADXL362_STATUS_ACT == 0)));
/* Get the data from the device and display it. */
// if(status & ADXL362_STATUS_DATA_RDY)
//{
ADXL362_GetXyz(&xAxis, &yAxis, &zAxis);
if(xAxis!=0)
{
P1OUT |=0X01;
__delay_cycles(1000);
P1OUT &=~0X01;
}
if(yAxis!=0)
{
P1OUT |=0X01;
__delay_cycles(1000);
P1OUT &=~0X01;
_delay_cycles(2000);
P1OUT |=0x01;
}
if(zAxis!=0)
{
P1OUT |=0X01;
__delay_cycles(1000);
P1OUT &=~0X01;
__delay_cycles(2000);
P1OUT |=0X01;
__delay_cycles(1000);
P1OUT &=~0X01;
}
//}
/* Display the activity/inactivity status. */
}
}
ADXL362.C
#include "ADXL362.h"
#include "Communication.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/***************************************************************************//**
* @brief Initializes communication with the device and checks if the part is
* present by reading the device id.
*
* @return 1 if the initialization was successful and the device is present,
* 0 if an error occurred.
*******************************************************************************/
unsigned char ADXL362_Init(void)
{
unsigned char regValue = 0;
unsigned char status = 0;
status = SPI_Init();
ADXL362_GetRegisterValue(®Value, ADXL362_REG_PARTID, 1);
if((regValue != ADXL362_PART_ID))
{
status = 0;
}
return status;
}
/***************************************************************************//**
* @brief Writes data into a register.
*
* @param registerValue - Data value to write.
* @param registerAddress - Address of the register.
* @param bytesNumber - Number of bytes. Accepted values: 0 - 1.
*
* @return None.
*******************************************************************************/
void ADXL362_SetRegisterValue(unsigned short registerValue,
unsigned char registerAddress,
unsigned char bytesNumber)
{
unsigned char buffer[4] = {0, 0, 0, 0};
buffer[0] = ADXL362_WRITE_REG;
buffer[1] = registerAddress;
buffer[2] = (registerValue & 0x00FF);
buffer[3] = (registerValue >> 8);
SPI_Write(ADXL362_SLAVE_ID, buffer, bytesNumber + 2);
}
/***************************************************************************//**
* @brief Performs a burst read of a specified number of registers.
*
* @param pReadData - The read values are stored in this buffer.
* @param registerAddress - The start address of the burst read.
* @param bytesNumber - Number of bytes to read.
*
* @return None.
*******************************************************************************/
void ADXL362_GetRegisterValue(unsigned char* pReadData,
unsigned char registerAddress,
unsigned char bytesNumber)
{
unsigned char buffer[32];
unsigned char index = 0;
buffer[0] = ADXL362_READ_REG;
buffer[1] = registerAddress;
for(index = 0; index < bytesNumber; index++)
{
buffer[index + 2] = pReadData[index];
}
SPI_Read(ADXL362_SLAVE_ID, buffer, bytesNumber + 2);
for(index = 0; index < bytesNumber; index++)
{
pReadData[index] = buffer[index + 2];
}
}
/***************************************************************************//**
* @brief Reads multiple bytes from the device's FIFO buffer.
*
* @param pBuffer - Stores the read bytes.
* @param bytesNumber - Number of bytes to read.
*
* @return None.
*******************************************************************************/
void ADXL362_GetFifoValue(unsigned char* pBuffer, unsigned short bytesNumber)
{
unsigned char buffer[512];
unsigned short index = 0;
buffer[0] = ADXL362_WRITE_FIFO;
for(index = 0; index < bytesNumber; index++)
{
buffer[index + 1] = pBuffer[index];
}
SPI_Read(ADXL362_SLAVE_ID, buffer, bytesNumber + 1);
for(index = 0; index < bytesNumber; index++)
{
pBuffer[index] = buffer[index + 1];
}
}
/***************************************************************************//**
* @brief Resets the device via SPI communication bus.
*
* @return None.
*******************************************************************************/
void ADXL362_SoftwareReset(void)
{
ADXL362_SetRegisterValue(ADXL362_RESET_KEY, ADXL362_REG_SOFT_RESET, 1);
}
/***************************************************************************//**
* @brief Places the device into standby/measure mode.
*
* @param pwrMode - Power mode.
* Example: 0 - standby mode.
* 1 - measure mode.
*
* @return None.
*******************************************************************************/
void ADXL362_SetPowerMode(unsigned char pwrMode)
{
unsigned char oldPowerCtl = 0;
unsigned char newPowerCtl = 0;
ADXL362_GetRegisterValue(&oldPowerCtl, ADXL362_REG_POWER_CTL, 1);
newPowerCtl = oldPowerCtl & ~ADXL362_POWER_CTL_MEASURE(0x3);
newPowerCtl = newPowerCtl |
(pwrMode * ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON));
ADXL362_SetRegisterValue(newPowerCtl, ADXL362_REG_POWER_CTL, 1);
}
/***************************************************************************//**
* @brief Selects the measurement range.
*
* @param gRange - Range option.
* Example: ADXL362_RANGE_2G - +-2 g
* ADXL362_RANGE_4G - +-4 g
* ADXL362_RANGE_8G - +-8 g
*
* @return None.
*******************************************************************************/
void ADXL362_SetRange(unsigned char gRange)
{
unsigned char oldFilterCtl = 0;
unsigned char newFilterCtl = 0;
ADXL362_GetRegisterValue(&oldFilterCtl, ADXL362_REG_FILTER_CTL, 1);
newFilterCtl = oldFilterCtl & ~ADXL362_FILTER_CTL_RANGE(0x3);
newFilterCtl = newFilterCtl | ADXL362_FILTER_CTL_RANGE(gRange);
ADXL362_SetRegisterValue(newFilterCtl, ADXL362_REG_FILTER_CTL, 1);
}
/***************************************************************************//**
* @brief Selects the Output Data Rate of the device.
*
* @param outRate - Output Data Rate option.
* Example: ADXL362_ODR_12_5_HZ - 12.5Hz
* ADXL362_ODR_25_HZ - 25Hz
* ADXL362_ODR_50_HZ - 50Hz
* ADXL362_ODR_100_HZ - 100Hz
* ADXL362_ODR_200_HZ - 200Hz
* ADXL362_ODR_400_HZ - 400Hz
*
* @return None.
*******************************************************************************/
void ADXL362_SetOutputRate(unsigned char outRate)
{
unsigned char oldFilterCtl = 0;
unsigned char newFilterCtl = 0;
ADXL362_GetRegisterValue(&oldFilterCtl, ADXL362_REG_FILTER_CTL, 1);
newFilterCtl = oldFilterCtl & ~ADXL362_FILTER_CTL_ODR(0x7);
newFilterCtl = newFilterCtl | ADXL362_FILTER_CTL_ODR(outRate);
ADXL362_SetRegisterValue(newFilterCtl, ADXL362_REG_FILTER_CTL, 1);
}
/***************************************************************************//**
* @brief Reads the 3-axis raw data from the accelerometer.
*
* @param x - Stores the X-axis data(as two's complement).
* @param y - Stores the X-axis data(as two's complement).
* @param z - Stores the X-axis data(as two's complement).
*
* @return None.
*******************************************************************************/
void ADXL362_GetXyz(short* x,short*y,short*z)
{
unsigned char N=ADXL362_REG_XDATA_L;
unsigned char count=0,i=0;
unsigned char xyz[6]={0,0,0,0,0,0};
unsigned char xyzValues[1];
for(i=0;i<6;i++)
{
xyzValues[0] =0;
ADXL362_GetRegisterValue(xyzValues,N,1);
N=N+1;
if(count==0)
{
xyz[0]=xyzValues[0];
}
else if(count==1)
{
xyz[1]=xyzValues[0];
*x = ((short)xyz[1]) + xyz[0];
}
else if(count==2)
{
xyz[2]=xyzValues[0];
}
else if(count==3)
{
xyz[3]=xyzValues[0];
*y = ((short)xyz[4]) + xyz[3];
}
else if(count==4)
{
xyz[4]=xyzValues[0];
}
else if(count==5)
{
xyz[5]=xyzValues[0];
*z = ((short)xyz[5]) + xyz[4];
}
count=count+1;
}
}
//void ADXL362_GetXyz(short* x, short* y, short* z)
//{
// unsigned char xyzValues[6] = {0, 0, 0, 0, 0, 0};
//ADXL362_GetRegisterValue(xyzValues, ADXL362_REG_XDATA_L, 6);
//*x = ((short)xyzValues[1] << 8) + xyzValues[0];
//*y = ((short)xyzValues[3] << 8) + xyzValues[2];
//*z = ((short)xyzValues[5] << 8) + xyzValues[4];
//}
/***************************************************************************//**
* @brief Reads the temperature of the device.
*
* @return tempCelsius - The value of the temperature(degrees Celsius).
*******************************************************************************/
float ADXL362_ReadTemperature(void)
{
unsigned char rawTempData[2] = {0, 0};
short signedTemp = 0;
float tempCelsius = 0;
ADXL362_GetRegisterValue(rawTempData, ADXL362_REG_TEMP_L, 2);
signedTemp = (short)(rawTempData[1] << 8) + rawTempData[0];
tempCelsius = (float)signedTemp * 0.065;
return tempCelsius;
}
/***************************************************************************//**
* @brief Configures the FIFO feature.
*
* @param mode - Mode selection.
* Example: ADXL362_FIFO_DISABLE - FIFO is disabled.
* ADXL362_FIFO_OLDEST_SAVED - Oldest saved mode.
* ADXL362_FIFO_STREAM - Stream mode.
* ADXL362_FIFO_TRIGGERED - Triggered mode.
* @param waterMarkLvl - Specifies the number of samples to store in the FIFO.
* @param enTempRead - Store Temperature Data to FIFO.
* Example: 1 - temperature data is stored in the FIFO
* together with x-, y- and x-axis data.
* 0 - temperature data is skipped.
*
* @return None.
*******************************************************************************/
void ADXL362_FifoSetup(unsigned char mode,
unsigned short waterMarkLvl,
unsigned char enTempRead)
{
unsigned char writeVal = 0;
writeVal = ADXL362_FIFO_CTL_FIFO_MODE(mode) |
(enTempRead * ADXL362_FIFO_CTL_FIFO_TEMP) |
ADXL362_FIFO_CTL_AH;
ADXL362_SetRegisterValue(writeVal, ADXL362_REG_FIFO_CTL, 1);
ADXL362_SetRegisterValue(waterMarkLvl, ADXL362_REG_FIFO_SAMPLES, 2);
}
/***************************************************************************//**
* @brief Configures activity detection.
*
* @param refOrAbs - Referenced/Absolute Activity Select.
* Example: 0 - absolute mode.
* 1 - referenced mode.
* @param threshold - 11-bit unsigned value that the adxl362 samples are
* compared to.
* @param time - 8-bit value written to the activity timer register. The amount
* of time (in seconds) is: time / ODR, where ODR - is the output
* data rate.
*
* @return None.
*******************************************************************************/
void ADXL362_SetupActivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned char time)
{
unsigned char oldActInactReg = 0;
unsigned char newActInactReg = 0;
/* Configure motion threshold and activity timer. */
ADXL362_SetRegisterValue((threshold & 0x7FF), ADXL362_REG_THRESH_ACT_L, 2);
ADXL362_SetRegisterValue(time, ADXL362_REG_TIME_ACT, 1);
/* Enable activity interrupt and select a referenced or absolute
configuration. */
ADXL362_GetRegisterValue(&oldActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
newActInactReg = oldActInactReg & ~ADXL362_ACT_INACT_CTL_ACT_REF;
newActInactReg |= ADXL362_ACT_INACT_CTL_ACT_EN |
(refOrAbs * ADXL362_ACT_INACT_CTL_ACT_REF);
ADXL362_SetRegisterValue(newActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
}
/***************************************************************************//**
* @brief Configures inactivity detection.
*
* @param refOrAbs - Referenced/Absolute Inactivity Select.
* Example: 0 - absolute mode.
* 1 - referenced mode.
* @param threshold - 11-bit unsigned value that the adxl362 samples are
* compared to.
* @param time - 16-bit value written to the inactivity timer register. The
* amount of time (in seconds) is: time / ODR, where ODR - is the
* output data rate.
*
* @return None.
*******************************************************************************/
void ADXL362_SetupInactivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned short time)
{
unsigned char oldActInactReg = 0;
unsigned char newActInactReg = 0;
/* Configure motion threshold and inactivity timer. */
ADXL362_SetRegisterValue((threshold & 0x7FF),
ADXL362_REG_THRESH_INACT_L,
2);
ADXL362_SetRegisterValue(time, ADXL362_REG_TIME_INACT_L, 2);
/* Enable inactivity interrupt and select a referenced or absolute
configuration. */
ADXL362_GetRegisterValue(&oldActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
newActInactReg = oldActInactReg & ~ADXL362_ACT_INACT_CTL_INACT_REF;
newActInactReg |= ADXL362_ACT_INACT_CTL_INACT_EN |
(refOrAbs * ADXL362_ACT_INACT_CTL_INACT_REF);
ADXL362_SetRegisterValue(newActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
}
#include "Communication.h"
#include "msp430.h"
#include "cc430f6137.h"
/******************************************************************************/
/* Variables Declarations */
/******************************************************************************/
unsigned char ID[3]={0x0B,0x02,0xff};
unsigned char id=0,xais=0;
unsigned char byte = 0;
/***************************************************************************//**
* @brief Initializes the SPI communication peripheral.
*
* @param lsbFirst - Transfer format (0 or 1).
* Example: 0x0 - MSB first.
* 0x1 - LSB first.
* @param clockFreq - SPI clock frequency (Hz).
* Example: 1000 - SPI clock frequency is 1 kHz.
* @param clockPol - SPI clock polarity (0 or 1).
* Example: 0x0 - Idle state for clock is a low level; active
* state is a high level;
* 0x1 - Idle state for clock is a high level; active
* state is a low level.
* @param clockEdg - SPI clock edge (0 or 1).
* Example: 0x0 - Serial output data changes on transition
* from idle clock state to active clock state;
* 0x1 - Serial output data changes on transition
* from active clock state to idle clock state.
*
* @return status - Result of the initialization procedure.
* Example: 1 - if initialization was successful;
* 0 - if initialization was unsuccessful.
*******************************************************************************/
unsigned char SPI_Init()
{
P1DIR=0XFF;
P1OUT=0X0;
P2DIR=0XFF;
P2DIR=0X0;
PMAPPWD = 0x02D52; // Get write-access to port mapping regs
P2MAP0 = PM_UCA0SIMO; // Map UCA0SIMO output to P2.0
P2MAP2 = PM_UCA0SOMI; // Map UCA0SOMI output to P2.2
P2MAP4 = PM_UCA0CLK; // Map UCA0CLK output to P2.4
PMAPPWD = 0; // Lock port mapping registers
P2OUT |= BIT1; // Set P1.0 for LED
// Set P1.2 for slave reset
P1DIR |= BIT0; // Set P1.0, P1.2 to output direction
P2DIR |= BIT0 + BIT1 + BIT2 + BIT4; // ACLK, MCLK, SMCLK set out to pins
P2SEL |= BIT0 + BIT2 + BIT4; // P2.0,2,4 for debugging purposes.
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL0 &= ~UCCKPL; //不工作时引脚低电平
UCA0CTL0 |=UCCKPH; //第一个沿捕获
UCA0CTL0 |= UCMST+UCSYNC+UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0x02; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
__bis_SR_register(GIE);
return 1;
}
/***************************************************************************//**
* @brief Reads data from SPI.
*
* @param slaveDeviceId - The ID of the selected slave device.
* @param data - Data represents the write buffer as an input parameter and the
* read buffer as an output parameter.
* @param bytesNumber - Number of bytes to read.
*
* @return Number of read bytes.
*******************************************************************************/
unsigned char SPI_Read(unsigned char slaveDeviceId,
unsigned char* data,
unsigned char bytesNumber)
{
unsigned char byte = 0;
P2OUT &= ~0X02;
for(byte = 0; byte < bytesNumber; byte++)
{
UCA0TXBUF=data[byte];
while (!(UCA0IFG&UCTXIFG));
__delay_cycles(10);
data[byte]= UCA0RXBUF;
}
__delay_cycles(20);
//test
// P2OUT &= ~0X02;
// while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
//UCA0TXBUF = 0x0B; // Transmit first character
//__delay_cycles(10);
// while (!(UCA0IFG&UCTXIFG));
//UCA0TXBUF = 0X02;
//__delay_cycles(10);
//while (!(UCA0IFG&UCTXIFG));
//UCA0TXBUF = 0x0;
//__delay_cycles(10);
//while (!(UCA0IFG&UCTXIFG));
//id=UCA0RXBUF;
//__delay_cycles(30);
P2OUT |=0X02;
__delay_cycles(10);
if(data[2]==0xf2)
{
P1OUT |=0X01;
}
else
{
P1OUT &=~0X01;
}
return bytesNumber;
}
void readx(void)
{
P2OUT &= ~0X02;
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0x0B; // Transmit first character
__delay_cycles(10);
while (!(UCA0IFG&UCTXIFG));
UCA0TXBUF = 0X0E;
__delay_cycles(10);
while (!(UCA0IFG&UCTXIFG));
UCA0TXBUF = 0x0;
__delay_cycles(10);
while (!(UCA0IFG&UCTXIFG));
xais=UCA0RXBUF;
__delay_cycles(10);
P2OUT |=0X02;
}
/***************************************************************************//**
* @brief Writes data to SPI.
*
* @param slaveDeviceId - The ID of the selected slave device.
* @param data - Data represents the write buffer.
* @param bytesNumber - Number of bytes to write.
*
* @return Number of written bytes.
*******************************************************************************/
unsigned char SPI_Write(unsigned char slaveDeviceId,
unsigned char* data,
unsigned char bytesNumber)
{
unsigned char byte = 0;
//unsigned char read = 0;
P2OUT &= ~0x02;
for(byte = 0; byte < bytesNumber; byte++)
{
while (!(UCA0IFG&UCTXIFG));
UCA0TXBUF=data[byte];
__delay_cycles(10);
}
P2OUT |=0X02;
return bytesNumber;
}
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,4))
{
case 0: break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
// make sure slave can process information
break;
case 4: break; // Vector 4 - TXIFG
default: break;
}
}
这是根据官方的代码改的。 读加速度的函数流程是,先读x轴低位,然后x轴高位,然后y,z。
|