ADXL355不能进入测量模式,求解答

使用STM32的SPI进行模块通讯,能够正常读取ID寄存器,电源控制寄存器复位默认值为0x01,写入0x00后再次读取值还是0x01,查看电源是稳定正常的,求解答这种奇怪的问题。以下是我用逻辑分析仪抓取到的数据波形,以及代码:

这里是抓取到的读取ID寄存器的数据波形

这里是写入电源控制寄存器的值0x00

读取到的电源控制寄存器与温度寄存器的值

以下是代码

/*
函数功能:初始化ADXL355模块
参 数:无
返 回 值:无
*/

void ADXL355_Init(void)
{
SPIx_Init(SPI_2);
//STM_SPI1_Init();
GPIO_InitTypeDef GPIO_InitStructure;

//开启PA和PC口时钟
RCC_AHBPeriphClockCmd(ADXL355_CSN_GPIO_CLK | ADXL355_DRDY_GPIO_CLK, ENABLE);

GPIO_StructInit(&GPIO_InitStructure);

//CS和电源引脚初始化配置
//GPIO_InitStructure.GPIO_Pin = ADXL355_CSN_PIN | ADXL355_PWR_PIN;
GPIO_InitStructure.GPIO_Pin = ADXL355_CSN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(ADXL355_CSN_GPIO_PORT, &GPIO_InitStructure);
ADXL355_CS_HIGH(); //取消片选信号

//DRDY,INT1,INT2引脚初始化配置 PC6 PC7 PC8
//GPIO_InitStructure.GPIO_Pin = ADXL355_DRDY_PIN | ADXL355_INT2_PIN | ADXL355_INT1_PIN;
GPIO_InitStructure.GPIO_Pin = ADXL355_DRDY_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(ADXL355_DRDY_GPIO_PORT, &GPIO_InitStructure);


ADXL355_Reset(); //复位传感器
delay_ms(10);

uint8_t devID ;
uint8_t memsID;
uint8_t pritID;
uint8_t revID;
ReadDevID(&devID, &memsID, &pritID, &revID); //读取传感器ID
printf("devID: %0x, memsID: %0x,pritID: %0x, revID: %0x\r\n",devID, memsID, pritID, revID);



/*配置传感器寄存器参数*/
ADXL355_RegConfig();
/*
todo:
配置外部中断PC6 PC7 对应中断线2
PC8 对应中断线3
*/

// NVIC_InitTypeDef NVIC_InitStructure;
// EXTI_InitTypeDef EXTI_InitStructure;
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
// /* Enable the GPIOB Interrupt */
//
// NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//
//
// SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource6);
// EXTI_StructInit(&EXTI_InitStructure);//将各个参数清零
//
// EXTI_InitStructure.EXTI_Line = EXTI_Line6;
// EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
// EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
// EXTI_InitStructure.EXTI_LineCmd = ENABLE; //开中断
// EXTI_Init(&EXTI_InitStructure);
// delay_ms(10);

ADXL355_Reset(); //复位传感器
delay_ms(1000);

//进入测量模式
ADXL355_SetPowerMode(ADXL355_MEASMODE);
delay_ms(10);



//ADXL355_PWR_LOW(); //关闭电源输出
}

/*
函数功能:adxl355 向寄存器写数据函数
参 数:unsigned char addr, 需要写入的字节地址
unsigned char *data 需要写入的数据
返 回 值:无
*/
void WriteReg_ADXL355(uint8_t addr, uint8_t data)
{
ADXL355_CS_LOW(); //片选信号

STM_SPI2_WriteRead(addr<<1 | 0x00);

STM_SPI2_WriteRead(data);

ADXL355_CS_HIGH(); //取消片选信号
}


/*
函数功能:从adxl355中读取单字节数据
参 数:unsigned char addr, 需要读取的寄存器地址
unsigned char *pdata 读取到的数据返回值指针
返 回 值:无
*/
void ReadReg_ADXL355(uint8_t addr, uint8_t *pdata)
{

ADXL355_CS_LOW(); //片选信号

STM_SPI2_WriteRead(addr<<1 |0x01);

*pdata = STM_SPI2_WriteRead(0);

ADXL355_CS_HIGH(); //取消片选信号



}


/*
函数功能:从adxl355中读取多字节数据
参 数:unsigned uint8_t *addr, 需要读取的寄存器地址
unsigned uint8_t *pdata 读取到的数据返回值指针
int bytes 需要读取的字节数
返 回 值:无
*/
void ReadRegs_ADXL355(uint8_t addr, uint8_t *pdata, int bytes)
{

ADXL355_CS_LOW(); //片选信号

STM_SPI2_WriteRead(addr);
int i = 0;
for(i = 0; i< bytes; i++)
{
*pdata = STM_SPI2_WriteRead(0);
pdata ++;
}
ADXL355_CS_HIGH(); //取消片选信号
}

/*
函数功能:读取设备ID,MEMSID,当前版本ID,历史版本ID
0xAD 0x1D 0xED 0x00
参 数:uint8_t *devID, 设备ID指针
uint8_t *memsID, MEMSID指针
uint8_t *pritID, 当前版本ID指针
uint8_t *revID 历史版本ID指针
返 回 值:无
*/
void ReadDevID(uint8_t *devID, uint8_t *memsID, uint8_t *pritID, uint8_t *revID)
{

ReadReg_ADXL355(XL355_DEVID_AD, devID);

ReadReg_ADXL355(XL355_DEVID_MST, memsID);

ReadReg_ADXL355(XL355_PARTID, pritID);

ReadReg_ADXL355(XL355_REVID, revID);
}


/*
函数功能:复位adxl355设备
参 数:无
返 回 值:无
*/
void ADXL355_Reset(void)
{

WriteReg_ADXL355(XL355_RESET, ADXL355_REST);

}


/*
函数功能:设置adxl355电源工作模式
参 数:uint8_t mode 需要设置的工作模式
选择 ADXL355_STANDBY 待机模式
ADXL355_MEASMODE 测量模式
以上两种参数其中一种
返 回 值:无
*/
void ADXL355_SetPowerMode(uint8_t mode)
{

WriteReg_ADXL355(XL355_POWER_CTL, mode);
}


/*
函数功能:配置adxl355寄存器
参 数:无
返 回 值:无
*/
void ADXL355_RegConfig(void)
{
uint8_t setvalue = 0x00;
/*
设置滤波寄存器输出速率
关闭高通滤波使能,设置低通滤波输出范围125 Hz and 31.25 Hz
*/
setvalue = ADXL355_HPF_CORNER_OFF|ADXL355_LPF_125;
WriteReg_ADXL355(XL355_FILTER, setvalue);
delay_ms(1);
/*
选择中断极性和测量范围
高电平产生中断,2g测量范围
*/
setvalue = (0x01 << 6)|(0x01<<0);
WriteReg_ADXL355(XL355_RANGE, setvalue);

delay_ms(1);
/*
配置FIFO中存储样本数量
*/
// setvalue = 0x60; //FIFO中最大存储96条样本数据
// WriteReg_ADXL355(XL355_FIFO_SAMPLES, setvalue);
//
/*
活动检测功能关闭
*/
//默认关闭活动使能,阈值,和活动检测计数值

/*
开启FIFO_FULL和RDY中断使能位
*/
//FIFO_FULL在INT2引脚上生成中断信号,RDY在INT1引脚上生成中断信号
// setvalue = ADXL355_INT_FULL_EN2|ADXL355_INT_RDY_EN1;
// WriteReg_ADXL355(XL355_INT_MAP, &setvalue);

/*
外部同步功能默认关闭
*/


/*
开启自测功能
*/

// setvalue = ADXL355_ST2_TEST | ADXL355_ST1_TEST;
// WriteReg_ADXL355(XL355_SELF_TEST, setvalue);
// delay_ms(1);
// //关闭自测功能,开始正常工作
// setvalue = 0x00;
// WriteReg_ADXL355(XL355_SELF_TEST, setvalue);

}

/*
函数功能:读取adxl355寄存器温度数据
参 数:无
返 回 值:读取到的值

*/
float ADXL355_Temperature(void)
{
short Temp = 0;
uint8_t tempH = 0;
uint8_t tempL = 0;
ReadReg_ADXL355(XL355_TEMP2, &tempH);
ReadReg_ADXL355(XL355_TEMP1, &tempL);

Temp = (short)(tempH&0x0F) << 8 | tempL;

float Temperature = (float)((Temp - ADXL355_TEMP_BIAS)/ADXL355_TEMP_SLOPE + 25);

return Temperature;
}


/*
函数功能:转换adxl355角度数据
参 数:需要转换的加速度值
返 回 值: 有符号整型角度值
*/
int ADXL355_Acceleration_Data_Conversion (uint32_t ui32SensorData)
{
int volatile i32Conversion = 0;

ui32SensorData = (ui32SensorData >> 4);
ui32SensorData = (ui32SensorData & 0x000FFFFF);

if((ui32SensorData & 0x00080000) == 0x00080000){

i32Conversion = (ui32SensorData | 0xFFF00000);

}
else{
i32Conversion = ui32SensorData;
}

return i32Conversion;
}


/*
函数功能:读取adxl355角度寄存器数据
参 数:无
返 回 值:-1 失败
1 成功

*/
int ADXL355_XYZ_AXIS(int *Xangle, int *Yangle, int *Zangle)
{
uint8_t angleH = 0;
uint8_t angleM = 0;
uint8_t angleL = 0;
uint8_t state = 0;
int i =0;
do
{
ReadReg_ADXL355(XL355_STATUS, &state);//读取状态寄存器
i ++;
}while(!(state&0x01)&&i<500);

if(i >=500)
{
*Xangle = 0.00;
*Yangle = 0.00;
*Zangle = 0.00;
return -1;
}


ReadReg_ADXL355(XL355_XDATA3, &angleH);
ReadReg_ADXL355(XL355_XDATA2, &angleM);
ReadReg_ADXL355(XL355_XDATA1, &angleL);
uint32_t ui32SensorX = ((uint32_t)angleH << 12)|(uint32_t)(angleM << 4) | (angleL&0xF0>>4);

*Xangle = ADXL355_Acceleration_Data_Conversion(ui32SensorX);




ReadReg_ADXL355(XL355_YDATA3, &angleH);
ReadReg_ADXL355(XL355_YDATA2, &angleM);
ReadReg_ADXL355(XL355_YDATA1, &angleL);
uint32_t ui32SensorY = ((uint32_t)angleH << 12)|(uint32_t)(angleM << 4) | (angleL&0xF0>>4);
*Yangle = ADXL355_Acceleration_Data_Conversion(ui32SensorY);


ReadReg_ADXL355(XL355_ZDATA3, &angleH);
ReadReg_ADXL355(XL355_ZDATA2, &angleM);
ReadReg_ADXL355(XL355_ZDATA1, &angleL);
uint32_t ui32SensorZ = ((uint32_t)angleH << 12)|(uint32_t)(angleM << 4) | (angleL&0xF0>>4);
*Zangle = ADXL355_Acceleration_Data_Conversion(ui32SensorZ);


return 0;
}

/*
函数功能:从FIFO中读取adxl355角度数据
参 数:无
返 回 值:读取到的值
*/
int ADXL355_FIFOREAD_AXIS(int *Xangle, int *Yangle, int *Zangle)
{

int X_angle = 0, Y_angle = 0, Z_angle = 0;
uint8_t angleXbuff[3] = {0};
uint8_t angleYbuff[3] = {0};
uint8_t angleZbuff[3] = {0};
int i = 0;
do
{
i ++;
}
while((!g_Flag_adxl355_int)&&(i < 500));
if(i >= 500)
{
*Xangle = 0.00;
*Yangle = 0.00;
*Zangle = 0.00;
return -1;
}

g_Flag_adxl355_int = 0; //清除中断读取标志位

ReadRegs_ADXL355(XL355_FIFO_DATA, angleXbuff, 3);
ReadRegs_ADXL355(XL355_FIFO_DATA, angleYbuff, 3);
ReadRegs_ADXL355(XL355_FIFO_DATA, angleZbuff, 3);

X_angle = (int)((angleXbuff[0]&0xF0>>4) << 16)|(short)(angleXbuff[1] << 8) | angleXbuff[2];
uint8_t offset_X_H = 0;
uint8_t offset_X_L = 0;
ReadReg_ADXL355(XL355_OFFSET_X_H, &offset_X_H);
ReadReg_ADXL355(XL355_OFFSET_X_L, &offset_X_L);
X_angle = X_angle + ((int)(offset_X_H << 8)|(offset_X_L));
*Xangle = ADXL355_Acceleration_Data_Conversion(X_angle);

Y_angle = (int)((angleXbuff[0]&0xF0>>4) << 16)|(short)(angleYbuff[1] << 8) | angleYbuff[2];
uint8_t offset_Y_H = 0;
uint8_t offset_Y_L = 0;
ReadReg_ADXL355(XL355_OFFSET_Y_H, &offset_Y_H);
ReadReg_ADXL355(XL355_OFFSET_Y_L, &offset_Y_L);
Y_angle = Y_angle + ((int)(offset_Y_H << 8)|(offset_Y_L));
*Yangle = ADXL355_Acceleration_Data_Conversion(Y_angle);

Z_angle = (int)((angleXbuff[0]&0xF0>>4) << 16)|(short)(angleZbuff[1] << 8) | angleZbuff[2];
uint8_t offset_Z_H = 0;
uint8_t offset_Z_L = 0;
ReadReg_ADXL355(XL355_OFFSET_Z_H, &offset_Z_H);
ReadReg_ADXL355(XL355_OFFSET_Z_L, &offset_Z_L);
Z_angle = Z_angle + ((int)(offset_Z_H << 8)|(offset_Z_L));
*Zangle = ADXL355_Acceleration_Data_Conversion(Z_angle);

printf("X_angle = %d, Y_angle = %d, Z_angle = %d\r\n",X_angle, Y_angle, Z_angle);

return 0;

}


/*
外部中断服务函数
*/
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line6) != RESET)
{
EXTI_ClearFlag(EXTI_Line6);
EXTI_ClearITPendingBit(EXTI_Line6); //清中断标志
g_Flag_adxl355_int = 1;

}

}