cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to read WhoAmI register from LIS3DSH. I'm using I2C

Gowtham  sk
Associate II
Posted on April 13, 2018 at 15:28

Hello guys,

The LIS3DSH is on the development board itself, which is STM32F407G (ver MB997D). And I am using CubeMX to generate the code.

Here is the wiring

Function

LIS3DSH

Master

SDA

PA7

PINB7

SCL

PA5

PINB6

SEL/SDO

PA6

3V Pin

At first, I used these two API calls before I realised that HAL_I2C_Mem_Write and HAL_I2C_Mem_Read are the

right ones.

uint8_t slavAddr = 0x3A; //[7-bit adddress is 0001 111x]
uint8_t ID,whoAmI=0x0F;
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
HAL_I2C_Master_Transmit(&hi2c1,slavAddr,&whoAmI,1,100);
HAL_I2C_Master_Receive(&hi2c1,slavAddr,&ID,1,100);
while (1)
{
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Surprisingly I got the default value of Who_Am_I, 0x3F (on the watch window) with the above program. But it wouldn't get every time and realized the mistake and used theHAL_I2C_Mem_Write

and

HAL_I2C_Mem_Read functions. I still don't get the output.

uint8_t slavAddr = 0x3A; //[7-bit adddress is 0001 111x]
uint8_t ID,whoAmI=0x0F;
uint8_t ctrlAddr = 0x20;
uint8_t ctrlVal = 0x17;
uint8_t xAddr[2] = {0x28,0x29};
//uint8_t yAddr[2] = {0x2A,0x2B};
//uint8_t zAddr[2] = {0x2C,0x2D};
uint8_t xVal[2],yVal[2],zVal[2];

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
//HAL_I2C_Master_Transmit(&hi2c1,slavAddr,&whoAmI,1,100);
//HAL_I2C_Master_Receive(&hi2c1,slavAddr,&ID,1,100);
HAL_I2C_Mem_Read(&hi2c1,slavAddr,whoAmI,1,&ID,1,100);
HAL_I2C_Mem_Write(&hi2c1,slavAddr,ctrlAddr,1,&ctrlVal,1,100);
HAL_I2C_Mem_Read(&hi2c1,slavAddr,xAddr[0],1,&xVal[0],1,100);
while (1)
 {
 }
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

This is my post ever on any forum. I might have missed out details

Help is appreciated.

3 REPLIES 3
T J
Lead
Posted on April 16, 2018 at 03:00

I didn't check your code, just show the obvious...

uint8_t slavAddr = 0x3A; //[7-bit adddress is NOT 0001 111x]

??

in IIC you have to shift the address up one bit.

HAL_I2C_Mem_Read(&hi2c1,slavAddr<<1,whoAmI,1,&ID,1,100);

Posted on April 20, 2018 at 18:35

Hello, T J..

Thanks for replying.

Here is the description of the function HAL_I2C_Master_Transmit,which mentions, that 'right shift by1' has to be done. I crossed checked with the user manual from

https://bit.ly/2Aq7Gmi

/**
 * @param DevAddress Target device address: The device 7 bits address value
 * in datasheet must be shift at right before call interface
 */
HAL_I2C_Master_Transmit(&hi2c1,slavAddr,&whoAmI,1,100);

But, here's the description of the functionHAL_I2C_Mem_Read,

which doesn't mention, that '

right shift by1

' has to be done.

/**
 * @param DevAddress Target device address
 */
HAL_I2C_Mem_Read(&hi2c1,slavAddr,whoAmI,1,&ID,1,100);

Anyway, I tried with what you had suggested. I still don't get the value '0x3F' in variable 'ID'.

HAL_I2C_Mem_Read(&hi2c1,slavAddr<<1,whoAmI,1,&ID,1,100);

Like, mentioned in the question, I did get the value once when I used the following function, even though the address is not right shifted. But then when I tried again with the same function, I didn't get.

HAL_I2C_Master_Transmit(&hi2c1,slavAddr,&whoAmI,1,100);

What could be the problem?

The slave address is also correct.Pins are rightly configured and set.

Could there be any problem with clock ?. I have set the I2C clock to 400Hz. I tried 200Hz also, it didn't work either.

Posted on April 21, 2018 at 02:46

Just to be sure,

please check you have 3 connections to the chip,

Lis3dsh connections to processor

4 - I2C serial clock (SCL)  to  PB6

5 - GND 0V                  < - this may be your problem.

6 - I2C serial data (SDA)  to  PB7

Pins 4 and 6 are pulled up with 10k  or 1k for fast IIC.

and you have a proper solid ground connection between the chips.

your slave address must be shifted 1 bit.

it is a simple interface to use.

PB6 I2C1_SCL

PB7 I2C1_SDA,

You need a good solid ground pin/wire.

this code works:

struct DacIIC {

    uint8_t DacTxBuffer[8];

    uint8_t DacRxBuffer[8];   // not used

};

♯ define MCP4728_DacAddress 0x60 << 1

void write4Dacs(void) {

    struct DacIIC MCP4728IIC;   

    HAL_StatusTypeDef IIC_Response;

 

    //Channel 0

    Dac0_Value  =  (4096 * 1) / 5;      // 1V

    MCP4728IIC.DacTxBuffer[0] =  (Dac0_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[1] =   Dac0_Value & 0x00ff;

    //Channel 1

    Dac1_Value  = Dac0_Value + (4096 * 1) / 5;      // 2V

    MCP4728IIC.DacTxBuffer[2] =  (Dac1_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[3] =   Dac1_Value & 0x00ff;

    //Channel 2

    Dac2_Value  = Dac1_Value + (4096 * 1) / 5;      // 3V

    MCP4728IIC.DacTxBuffer[4] =  (Dac2_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[5] =   Dac2_Value & 0x00ff;

    //Channel 3

    Dac3_Value  = Dac2_Value + (4096 * 1) / 5;      // 4V

    MCP4728IIC.DacTxBuffer[6] =  (Dac3_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[7] =   Dac3_Value & 0x00ff;

    IIC_Response = HAL_I2C_Master_Transmit(&hi2c1, MCP4728_DacAddress, &MCP4728IIC.DacTxBuffer[0], 8, 10);

}