Skip to main content
Visitor II
April 13, 2018
Question

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

  • April 13, 2018
  • 1 reply
  • 1725 views
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.

    This topic has been closed for replies.

    1 reply

    Visitor II
    April 16, 2018
    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);

    Visitor II
    April 20, 2018
    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.

    Visitor II
    April 21, 2018
    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);

    }