2018-03-04 09:22 PM
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) // Readvoid 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 #adxl3452018-03-05 01:07 AM
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
2018-03-05 01:09 AM
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 ?
2018-03-05 07:41 AM
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.
2018-03-05 07:45 AM
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.
2018-03-05 08:19 AM
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.
2018-03-05 10:31 AM
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)
// okelse // (...)2018-03-06 01:14 PM
in your original post, this seems wrong.
#define WRT (0x3A<<1) // Write
#define RD (0x3B<<1) // Readthe 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 bythe R/W bit. This translates to 0x3A for a write and 0x3B for aread. 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 anyunused pins; therefore, there is no known state or default statefor 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 thatthe ALT ADDRESS pin be connected to either VDD I/O or GNDwhen using I2C.'2018-03-06 01:40 PM
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) andADRESS_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:Commonvoid 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;
Thank you all for responses and helps.
Best Regards
2018-03-06 04:54 PM
I2C-bus specification and user manual: