cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4Discovery ADXL345 I2C Problem

Mustafa BAKIRCIOGLU
Associate II
Posted on March 05, 2018 at 06:22

Hello;

I have started to work on I2C communication by examining adxl345 sensor. I wrote basic code to test if my code works or not. According to the ADXL345 technical documentation, the 0x00 register should return device id which is 0xE5.When I tried this register , the return value is 0. This application should be basic but I guess , I still missing something. Beside my experience, I also make a search at this community about the adxl345 problems,but I could not find answer. I would be very appreciated if you guide me in this problems. I attached my code.

&sharpinclude 'stm32f4xx.h' // Device header

&sharpinclude 'stm32f4xx_hal_conf.h' // Keil::Device:STM32Cube Framework:Classic

&sharpinclude 'stm32f4xx_hal.h' // Keil::Device:STM32Cube HAL:Common

&sharpdefine SensAddr  0x1D // 7-bit Address of device

&sharpdefine WRT (0x3A<<1) // Write

&sharpdefine RD (0x3B<<1) // Read

void SysTick_Handler(void)

{

HAL_IncTick();

HAL_SYSTICK_IRQHandler();

}

void SysClockEn();

/*System Configuration PA8-> I2C Clock , PC9-> I2C Data Lane*/

int main(){

SysClockEn();

HAL_Init();

/*------GPIO Configuration For I2C3------*/

__GPIOA_CLK_ENABLE();

GPIO_InitTypeDef *ptrB6,addrB6;

ptrB6 = &addrB6;

ptrB6->Alternate = GPIO_AF4_I2C3;

ptrB6->Pin = GPIO_PIN_8;

ptrB6->Pull = GPIO_NOPULL;

ptrB6->Speed =GPIO_SPEED_FREQ_HIGH;

ptrB6->Mode = GPIO_MODE_AF_OD;

HAL_GPIO_Init(GPIOA,ptrB6);

__GPIOC_CLK_ENABLE();

GPIO_InitTypeDef *ptrC,addrC;

ptrC = &addrC;

ptrC->Alternate =GPIO_AF4_I2C3;

ptrC->Mode =GPIO_MODE_AF_OD;

ptrC->Pin =GPIO_PIN_9;

ptrC->Pull =GPIO_NOPULL;

ptrC->Speed =GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOC,ptrC);

/*-----I2C Configurations-----*/

//__HAL_RCC_I2C3_CLK_ENABLE();

__I2C3_CLK_ENABLE();

I2C_HandleTypeDef *ptrI2C,addrI2C;

ptrI2C = &addrI2C;

ptrI2C->Instance = I2C3;

ptrI2C->Init.ClockSpeed = 100000; //100Khz

ptrI2C->Init.DutyCycle = I2C_DUTYCYCLE_2;

ptrI2C->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

ptrI2C->Mode =HAL_I2C_MODE_MASTER;

//ptrI2C->Init.GeneralCallMode =I2C_GENERALCALL_DISABLE;

//ptrI2C->Init.NoStretchMode=I2C_NOSTRETCH_DISABLE;

HAL_I2C_Init(ptrI2C);

__HAL_I2C_ENABLE(ptrI2C);

uint8_t data=0x00;

unsigned char buffer[2];

uint8_t *buf;

unsigned char pt;

uint32_t ptr;

uint8_t val;

while(1){

val=HAL_I2C_IsDeviceReady(ptrI2C,0x1D,0xe5,1000);

pt=HAL_I2C_GetState(ptrI2C);

//HAL_I2C_Master_Transmit(ptrI2C,0x1d,0x00,1,0);

//HAL_I2C_Master_Receive(ptrI2C,0x1d,buffer,1,100);

//HAL_Delay(2);

HAL_I2C_Mem_Read(ptrI2C,

SensAddr

,0x00,1,buffer,2,1000);

ptr=HAL_I2C_GetError(ptrI2C);

}

}

void SysClockEn(){

__PWR_CLK_ENABLE();

}

#i2c #stm32f4-discovery #hal-i2c #adxl345
10 REPLIES 10
Posted on March 05, 2018 at 10:07

Do you have an oscilloscope, logic analyser, or other test gear to see what's actually happening on the the wires?

Are you sure you have the correct I2C address, and are you sure you are using it correctly?

http://www.avrfreaks.net/comment/2126096comment-2126096

The HAL_I2C_... functions all return a status result, but you are ignoring it. Don't do that!

At the very least, send it out of a UART so that you can see what's happening

http://www.addletters.com/pictures/bart-simpson-generator/bart-simpson-generator.php?line=I+will+not+ignore+API+status+return+codes

AvaTar
Lead
Posted on March 05, 2018 at 10:09

No F4 discovery version I know uses a ADXL345, so you presumably use an external board (breakout or prototype).

Do you have proper pull-up resistors ?

Using a scope, did you check the address on the bus ?

And do you see an acknowledge ?

Posted on March 05, 2018 at 15:41

Thank you

Neil.Andrew

‌;

I will examine with logic analyser, I checked the device I2C adresses and according to the datasheet I tried every implementation. Maybe the problem is about the external sensor board. I will check the SCL and SDA lines.

Posted on March 05, 2018 at 15:45

meyer.frank

‌, yes stm32f4 does not have adxl345 on board. I am using external sensor board. I used pull-up resistor 2k for each SDA and SDL line. In the Internet I saw some people uses 4.7k pull-up resistor, Do you think it affects the result?

I will check the SDA and SCL lines using logic analyser. I guess I can see what is going on ? Maybe the problem is on the external board. Thanks.

Posted on March 05, 2018 at 16:19

I used pull-up resistor 2k for each SDA and SDL line. In the Internet I saw some people uses 4.7k pull-up resistor, Do you think it affects the result?

Presumably not, depending on devices, 1k .. 10k will work. A value of 2k look fine.

Having no pull-ups will definitely not work.

I will check the SDA and SCL lines using logic analyser. I guess I can see what is going on ?

A slave device does an Acknowledge (pull bit 9 of a transmission low) in most cases of transfer.

This would be the first thing to check - besides levels and waveforms.

Be aware that a logic analyzer has trigger inputs, and thus only knows H an L.

it might hide trouble you would see with a scope.

Rosiney Silva
Associate II
Posted on March 05, 2018 at 19:31

I own this sensor and here it works using the address 0x53 (remembering that the address depends on 'ALT ADDRESS pin, Pin 12'

.).

This is required: 'ADXL345_ADDRESS_ALT_0 << 1'.

// I2C Address

#define ADXL345_ADDRESS_ALT_0  0x53U

#define ADXL345_ADDRESS_ALT_1  0x1DU

#define ADXL345_ADDRESS              (ADXL345_ADDRESS_ALT_0 << 1)

#define I2C_TIMEOUT   10 // ms

#define ADXL345_DEVID       0x00

#define ADXL345_DEVID_ID  0xE5

// (...)

uint8_t id;

if (HAL_I2C_Mem_Read(handle, ADXL345_ADDRESS, ADXL345_DEVID, I2C_MEMADD_SIZE_8BIT, &id, 1, I2C_TIMEOUT) == HAL_OK)

  // ok

else

  // (...)
T J
Lead
Posted on March 06, 2018 at 22:14

in your original post, this seems wrong.

#define WRT (0x3A<<1) // Write

#define RD (0x3B<<1) // Read

the device address is 0x1D ?

<<1   shifted for IIC address

is 0x3A

not 0x3A <<1

Relevant text from Datasheet:

'With the ALT ADDRESS pin

high, the 7-bit I2C address for the device is 0x1D, followed by

the R/W bit. This translates to 0x3A for a write and 0x3B for a

read. An alternate I2C address of 0x53 (followed by the R/W bit)

can be chosen by grounding the ALT ADDRESS pin (Pin 12).

This translates to 0xA6 for a write and 0xA7 for a read.

There are no internal pull-up or pull-down resistors for any

unused pins; therefore, there is no known state or default state

for the CS or ALT ADDRESS pin if left floating or unconnected.

It is required that the CS pin be connected to VDD I/O and that

the ALT ADDRESS pin be connected to either VDD I/O or GND

when using I2C.'
Posted on March 06, 2018 at 21:40

meyer.frank

Neil.Andrew

Silva.Rosiney

thank you for replies, as you said I checked the I2C lines response and result is the NACK. According to the

ADRESS_ALT_0(SDO ground & devadress = 0x53) and

ADRESS_ALT_1 ( SDO vcc & 0x1D device adress )

are tried. Every time I get NACK. I guess problem is about the sensor board. I attached the latest code.

#include ''stm32f4xx.h'' // Device header

#include ''stm32f4xx_hal_conf.h'' // Keil::Device:STM32Cube Framework:Classic

#include ''stm32f4xx_hal.h'' // Keil::Device:STM32Cube HAL:Common

void SysTick_Handler(void)

{

HAL_IncTick();

HAL_SYSTICK_IRQHandler();

}

int main(){

HAL_Init();

__PWR_CLK_ENABLE();

/*GPIO Settings According to the alternate mode -> I2C1_SDA PB7, I2C_SCL PB8*/

__GPIOB_CLK_ENABLE();

GPIO_InitTypeDef *ptrB,addrB;

ptrB=&addrB;

ptrB->Alternate = GPIO_AF4_I2C1;

ptrB->Mode = GPIO_MODE_AF_OD;

ptrB->Pin = GPIO_PIN_7 | GPIO_PIN_8;

ptrB->Pull = GPIO_NOPULL;

ptrB->Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB,ptrB);

/*I2C SETTINGS FOR I2C1*/

__I2C1_CLK_ENABLE();

I2C_HandleTypeDef *ptri2c,addri2c;

ptri2c=&addri2c;

ptri2c->Instance=I2C1;

ptri2c->Init.ClockSpeed = 100000; //100Khz

ptri2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

ptri2c->Init.OwnAddress1 = 0;

ptri2c->Init.DutyCycle = I2C_DUTYCYCLE_2;

ptri2c->Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;

ptri2c->Mode = HAL_I2C_MODE_MASTER;

//ptri2c->Devaddress = (0x1D<<1);

HAL_I2C_Init(ptri2c);

uint8_t data[1];

int x=0;

uint8_t id;

while(1){

//HAL_I2C_Master_Transmit(ptri2c,(0x53<<1),0x00,1,1);

//HAL_I2C_Master_Receive(ptri2c,(0x53<<1),data,1,1);

if(HAL_I2C_Mem_Read(ptri2c,(0x53U<<1),(uint8_t)0x00,I2C_MEMADD_SIZE_8BIT,&id,1,1) == HAL_OK){

x=1;

}

else{

x=-1;

}

HAL_Delay(1/10);

}

}

The Logic Analyser Result;

0690X00000609piQAA.png

Thank you all for responses and helps.

Best Regards

Posted on March 07, 2018 at 00:54

I2C-bus specification and user manual:

https://www.nxp.com/docs/en/user-guide/UM10204.pdf