LIS3MDL always output magnetic data 0 wrongly
Hello, support team.
In my design, I use 4-wire spi to transfer data between STM32F407 and LIS3MDL.
Here is my configuration to LIS3MDL.
CTRL_REG2 0x40 //Full-scale selection ±12 Gauss
CTRL_REG1 0x02 //XY low-power mode ODR 1000Hz
CTRL_REG4 0x00 //Z low-power mode ODR 1000Hz
CTRL_REG3 0x00 //Continuous-conversion mode
CTRL_REG5 0x40 //block data update for magnetic data.
The questions are as follows.
1.In the main function, firstly, I check the data from WHO_AM_I register. The output data is not 0x3D(default) but 0xFF. I don't know the reason. Does that affect anything?
2.Then, I write data CTRL_REG2_SOFT_RST(0x04) to CTRL_REG2 to reset the register. The output data from CTRL_REG2 to CTRL_REG5 are the same as the default data. ButI wonder why the output data from CTRL_REG1 is 0x18 (default data is 0x10). Does that affect anything?
3.After 2, I initialize the register as the data and order listed above. The data output by 4-wire SPI is the same as what I wirte.
4.Finally, I use the STATUS_REG register to help the data collecting (as the DoclD027014 AN4602 Application note). However, the detecting manegtic data result is totally wrong! It output data "0" of X,Y and Z continulsy, which is absolutely wrong. I don't know what happened cause I wrote the accurate configuration data to the register.
Here is my code.
How can I read magnetic data accurately at 1kHz speed?
Hope for your early reply. Thanks
Penghao
int main(void)
{
unsigned char STATUS,flag;
//help the STATUS_REG
float *Data;
Debug_USART_Config();
SPI3_Init();
printf("%x\n",READ_DATA_SPI(ADD_WHO_AM_I_R));
WRITE_DATA_SPI(ADD_CTRL_REG2_W,CTRL_REG2_SOFT_RST);
printf("%x %x %x %x %x\n",READ_DATA_SPI(ADD_CTRL_REG1_R),READ_DATA_SPI(ADD_CTRL_REG2_R),READ_DATA_SPI(ADD_CTRL_REG3_R),READ_DATA_SPI(ADD_CTRL_REG4_R),READ_DATA_SPI(ADD_CTRL_REG5_R));
LIS3MDL_init(CTRL_REG1_1000,CTRL_REG2_12,CTRL_REG3_CM,CTRL_REG4_1000,CTRL_REG5_BDU);
printf("%x %x %x %x %x\n",READ_DATA_SPI(ADD_CTRL_REG1_R),READ_DATA_SPI(ADD_CTRL_REG2_R),READ_DATA_SPI(ADD_CTRL_REG3_R),READ_DATA_SPI(ADD_CTRL_REG4_R),READ_DATA_SPI(ADD_CTRL_REG5_R));
// 02 40 00 00 40
while(1)
{
STATUS = READ_DATA_SPI(ADD_STATUS_REG_R);
flag = STATUS & ((uint8_t)0x08);
if (flag == ((uint8_t)0x08))
{
while(1)
{
STATUS = READ_DATA_SPI(ADD_STATUS_REG_R);
flag = STATUS & ((uint8_t)0x80);
if(flag == ((uint8_t)0x80))
{
break;
}
}
LIS3MDL_read(Data);
printf("%x=%f=%f=%f\n",READ_DATA_SPI(ADD_CTRL_REG2_R),Data[0],Data[1],Data[2]);
}
}
}void LIS3MDL_read(float *Data)
{
unsigned char buffer[6] = {0};
unsigned char f;
unsigned int Sensitivity = 0;
int i,j = 0;
int16_t cen = 0,ge,shi,bai,qian,wan;
buffer[0] = READ_DATA_SPI(ADD_OUT_X_H);
buffer[1] = READ_DATA_SPI(ADD_OUT_X_L);
buffer[2] = READ_DATA_SPI(ADD_OUT_Y_H);
buffer[3] = READ_DATA_SPI(ADD_OUT_Y_L);
buffer[4] = READ_DATA_SPI(ADD_OUT_Z_H);
buffer[5] = READ_DATA_SPI(ADD_OUT_Z_L);
f = READ_DATA_SPI(ADD_CTRL_REG2_R);
switch(f)
{
case CTRL_REG2_4:
Sensitivity = 6842;
break;
case CTRL_REG2_8:
Sensitivity = 3421;
break;
case CTRL_REG2_12:
Sensitivity = 2281;
break;
case CTRL_REG2_16:
Sensitivity = 1711;
break;
}
for(i = 0;i < 5;i = i+2)
{
cen = (int16_t)((((uint16_t)buffer[i]) << 8) + buffer[i+1]);
wan = cen / 10000;
qian = (cen - wan*10000) / 1000;
bai = (cen - wan*10000 - qian*1000) / 100;
shi = (cen - wan*10000 - qian*1000 - bai*100) / 10;
ge = cen - wan*10000 - qian*1000 - bai*100 - shi*10;
Data[j] = wan*10000 + qian*1000 + bai*100 + shi*10 + ge;
Data[j] = Data[j] / Sensitivity;
j++;
}
}@Eleon BORLINI (ST Employee)
@Miroslav BATEK (ST Employee)
