cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Discovery I2C LIS3DSH Problem

VAtab.1
Associate II

I have tried to work with LIS3DSH sensor using I2C protocol. I applied procedures on STM32f manual. But it didn't work. I wanna just receive x axis value. According to this, The GPIOD-12 will be on if it is less than 20. Maybe ı could not realise its failure. Anyone help me about that ? ahead of time, thanks.

#include "stm32f4xx.h"                  // Device header
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
 
#define SLAVE_ADRESS 0x1E   // LIS3DSH SENSOR ADDRESS
 
/*Prototype Functions*/
void I2C_START(I2C_TypeDef*,uint8_t,uint8_t );
void I2C_WRITE(I2C_TypeDef*,uint8_t);
void I2C_STOP(I2C_TypeDef*);
uint8_t I2C_READ_NACK(I2C_TypeDef*);
uint8_t I2C_READ_ACK(I2C_TypeDef*);
 
// Valuables
int8_t x=0,y=0,z=0;
uint8_t r_data=0;
 
int main()
{
	
	// Definitions
	GPIO_InitTypeDef    GPIO_InitStructure;
	I2C_InitTypeDef			I2C_InitStructure;
	
	
	// Clock Buses Configurations
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE| RCC_AHB1Periph_GPIOD |RCC_AHB1Periph_GPIOB,ENABLE );
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
  
	// LED PINS : RED YELLOW BLUE GREEN
	GPIO_InitStructure.GPIO_Pin		=	GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode	=	GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType	=	GPIO_OType_PP;	
	GPIO_Init(GPIOD,&GPIO_InitStructure);
	
	// 	LIS3DSH SEL PIN : 
	//	If SEL PIN is connected to ground, LIS3DSH address is 0x1E
	//	If SEL PIN is connected to voltage supply, LIS3DSH address is 0x1D
	GPIO_InitStructure.GPIO_Pin		=	GPIO_Pin_3; 
  GPIO_InitStructure.GPIO_Mode	=	GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType	=	GPIO_OType_PP;
	GPIO_Init(GPIOE,&GPIO_InitStructure);
	
	// I2C SDA & SLA PIN CONFIGURATIONS
	// NOTE : PINS must be set as PULL-UP.
	
	GPIO_InitStructure.GPIO_Mode	=	GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Pin		=	GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed	=	GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType	=	GPIO_OType_OD;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_UP;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_I2C1); // SCL
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_I2C1); // SDA
	
	I2C_InitStructure.I2C_Mode	=	I2C_Mode_I2C;
	I2C_InitStructure.I2C_ClockSpeed	=	100000;
	I2C_InitStructure.I2C_OwnAddress1	=	0x00;
	I2C_InitStructure.I2C_Ack	=	I2C_Ack_Disable;
	I2C_InitStructure.I2C_DutyCycle	=	I2C_DutyCycle_2;
	I2C_InitStructure.I2C_AcknowledgedAddress	=	I2C_AcknowledgedAddress_7bit;
	I2C_Init(I2C1,&I2C_InitStructure);
	
	I2C_Cmd(I2C1,ENABLE);
	
	GPIO_ResetBits(GPIOE,GPIO_PinSource3);  // SEL PIN IS SET. ADDRESS : 0x1E
	 
	
		
	while(1)
	{		
		// 100 HZ 9.2 G LIS3DSH SENSOR.
		I2C_START(I2C1,SLAVE_ADRESS<<1,I2C_Direction_Transmitter);
		I2C_WRITE(I2C1,0x20);
		I2C_WRITE(I2C1,0x67);
		I2C_STOP(I2C1);
		
		//	X  OUTPUT_L  
		I2C_START(I2C1,SLAVE_ADRESS<<1,I2C_Direction_Transmitter);
		I2C_WRITE(I2C1,0x28);
		I2C_START(I2C1,SLAVE_ADRESS<<1,I2C_Direction_Receiver);
		x	=	I2C_READ_NACK(I2C1);
		
		if(x!=0) 
		{
			GPIO_SetBits(GPIOD,GPIO_PinSource14);
		}
	}
}
void I2C_START(I2C_TypeDef* I2Cx, uint8_t adress, uint8_t direction)
{	
	while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_BUSY)); // wait until not be busy
	
	I2C_GenerateSTART(I2Cx,ENABLE);  // Occur the start condition
	while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT)); // EVENT 5 : 
 
	I2C_Send7bitAddress(I2Cx,adress,direction);
 
	// EVENT 6 :
	if(direction == I2C_Direction_Transmitter)
	{		
		while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
	}
	else if(direction == I2C_Direction_Receiver)     
	{
		while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
	}
}
 
void I2C_WRITE(I2C_TypeDef* I2Cx, uint8_t data)
{
  // EVENT 8.1 : 
	//while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTING));
	while(!(I2C1->SR1 & (1<<7)));
  
	I2C_SendData(I2Cx,data); // send datas
	
  // EVENT 8	: 
  while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); 	
}
 
uint8_t I2C_READ_NACK(I2C_TypeDef* I2Cx)
{
	I2C_AcknowledgeConfig(I2C1,DISABLE);
	I2C_GenerateSTOP(I2Cx,ENABLE);
	
	// EVENT 7 :
	while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_RECEIVED));
	
	r_data	=	I2C_ReceiveData(I2Cx);
	return r_data;
}
 
uint8_t I2C_READ_ACK(I2C_TypeDef* I2Cx)
{
	I2C_AcknowledgeConfig(I2C1,ENABLE);	
	// EVENT 7 :
	while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_RECEIVED));
	
	return I2C_ReceiveData(I2Cx);
}
 
void I2C_STOP(I2C_TypeDef* I2Cx)
{
	I2C_GenerateSTOP(I2Cx,ENABLE);
}

3 REPLIES 3

Hello

Note that old discovery boards have LIS302DL The rectangular one is LIS3DSH.

I don't see MEMS initialization code (power register, scale, data rate)

I don;t use SPL. to check the code

VAtab.1
Associate II

I have tried to work for both LIS302DL and LIS3DSH with all possibility. Also i researched it from other sources. I found one that is https://ayazfurkan.blogspot.com/2019/04/stm32f4-i2c-mpu6050.html. I tried it too. But it's fail.

On my code the MEMS Initialization is

I2C_START(I2C1,SLAVE_ADRESS<<1,I2C_Direction_Transmitter);
		I2C_WRITE(I2C1,0x20);
		I2C_WRITE(I2C1,0x67);
		I2C_STOP(I2C1);

0x20 ---> CTRL_REG_4 register

0x67 ---> X Y Z ENABLE, Data rate : 100hZ 9.2G

Yes, I have used Standard Peripheral Library (SPL) at KEİL as you say. I have checked my code more once. Maybe I overlook somethings.

As well as, I worked accelerator sensor via SPI protocol. But not with I2C Protocol.