2021-01-19 12:51 PM
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);
}
2021-01-19 02:43 PM
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
2021-01-20 11:04 AM
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.
2021-01-20 11:07 AM
As well as, I worked accelerator sensor via SPI protocol. But not with I2C Protocol.