cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DS3 SPI communication problem with STM32F4

DmytroMachkovskyi
Associate

Привіт! У мене проблема з отриманням даних із датчика LSM6DS3. Коли я намагаюся прочитати значення реєстру "WHO_AM_I", я отримую надто короткі імпульси у відповідь, які не можуть бути прочитані поданими до його тактового сигналу.

DmytroMachkovskyi_0-1716675423212.png

Я використовую цю плату з сенсором. SPI. Головним є STM32F411.

3v3 -> 3,3 В

GND -> GND

SA0 -> PA6 -> SPI1_MISO

CS -> PA4 -> GPIOA4
SDA -> PA7 ->  SPI1_MOSI

SCL -> PA5 ->  SPI1_SCK

У випадку, коли я надсилаю значення 0x8F, я отримую результат, як показано нижче. У той же час я повинен отримати значення 0x69 або 01101001 у двійковому вигляді. І якщо ви важливо подивіться на результати нижче, ви побачите, ніби щось заважає, імпульс занадто короткі, щоб їх можна було записати.

DmytroMachkovskyi_1-1716676173880.png

DmytroMachkovskyi_2-1716676417924.png

DmytroMachkovskyi_3-1716676549564.png

Я намагався прочитати значення в інших реєстрах "CTRL9_XL" і там така ситуація. Я повинен отримати 00111000, але я отримав 00110000, ніби імпульси не були стиснуті та записані на одне значення менше:

DmytroMachkovskyi_4-1716676645000.png

DmytroMachkovskyi_5-1716676662441.png

Налаштування SPI:

void SpiConfig(void){
 
RCC->APB2ENR |= (1 << 12);
////////////////////////////////////////////////// //////////
SPI1->CR1 |= (1 << 0) | (1 << 1); //CPHA=1 CPOL=1
SPI1->CR1 |= (1 << 2); //Майстер мод
SPI1->CR1 |= (2 << 3); //010: fPCLK/8 BR[2:0] 5 МГц SPI CLK
SPI1->CR1 &= ~(1 << 7); //LSBFIRST = 0 => спочатку MSB, потім LSB 
SPI1->CR1 |= (1 << 8) | (1 << 9); //Високий рівень SSI та SSM Керування програмним забезпеченням увімкнено
SPI1->CR1 &= ~(1 << 10); //RXONLY = 0 => Повний дуплексний мод
SPI1->CR1 &= ~(1 << 11); //8-бітний
SPI1->CR2 = 0;
}
Налаштування GPIO:
 
void SpiGPIOConfig(void){
RCC->AHB1ENR |= (1 << 0); //Увімкнути RCC для GPIO_A 
GPIOA->MODER |= (2 << 10) | (2 << 12) | (2 << 14) | (1 << 8);
//Альтернативна функція для PA5/6/7 загального виводу для PA4
GPIOA->MODER &= ~(1 << 9);  //Push-Pull для PA5/6/7/4 (за замовчуванням)
GPIOA->OSPEEDR |= (3 << 10) | (3 << 12) | (3 << 14) | (3 << 8); //Висока швидкість для PA5/6/7/4
GPIOA->AFR[0] |= (5 << 20) | (5 << 24) | (5 << 28); //AF5 (AFRL 0 - 7) на PA5/6/7
 
}
 
Передача:
 
void SPI_Transmit (uint8_t *дані, int size){
 
//1. Дочекатися встановлення біта TXE у стані реєстрації
int i = 0;
while(i < розмір){
 
while (!((SPI1->SR) & (1 << 1))){}; //Дочекайтеся інсталяції біта TXE -> Це вкажіть, що буфер порожній 
SPI1->DR = дані[i]; //Завантажити дані в реєстрі даних
i++;
}
while(!((SPI1->SR) & (1 << 1))){}; //Дочекайтеся інсталяції біта TXE -> Це вкажіть, що буфер порожній 
while(((SPI1->SR) & (1 << 7))){}; //Зачекайте, поки біт BSY скінеться -> Це означаємо, що SPI не зайняті комунікаціями
 
uint8_t temp = SPI1->DR;
температура = SPI1->SR;
 
}
 
Основна функція:
...
uint8_t RxData[6];
адреса uint8_t = 0x8f;
while(1){
 
CS_EN(); // потягнути шпильку низько
SPI_Transmit (&адреса, 1); // відправити адресу
SPI_Receive (RxData, 1); // отримати 1 байт даних
CS_DIS();  // витягнути шпильку високо
 
Delay_ms(1);
}
 
Якщо для пошуку помилки потрібно ще щось надати, то скажіть, все що потрібно надам
 
 
2 REPLIES 2
DmytroMachkovskyi
Associate

Everything was published in Ukrainian for some reason, I apologize. Dubbed in English:

Hello! I'm having a problem getting data from the LSM6DS3 sensor. When I try to read the value of the "WHO_AM_I" register, I get too short pulses in response that cannot be read by applying it to its clock.

I am using this sensor board. SPI. The main one is STM32F411.

3v3 -> 3.3V

GND -> GND

SA0 -> PA6 -> SPI1_MISO

CS -> PA4 -> GPIOA4
SDA -> PA7 -> SPI1_MOSI

SCL -> PA5 -> SPI1_SCK

In the case when I send the value 0x8F, I get the result as shown below. At the same time I should get the value 0x69 or 01101001 in binary form. And if you look carefully at the results below, you will see that something is interfering, the pulse is too short to be recorded.

I tried to read the value in other "CTRL9_XL" registers and there is such a situation. I should get 00111000, but I got 00110000, as if the pulses were not compressed and written one less value:

SPI settings:

void SpiConfig(void){

RCC->APB2ENR |= (1 << 12);
/////////////////////////////////////////////////// //////////
SPI1->CR1 |= (1 << 0) | (1 << 1); //CPHA=1 CPOL=1
SPI1->CR1 |= (1 << 2); //Master mod
SPI1->CR1 |= (2 << 3); //010: fPCLK/8 BR[2:0] 5 MHz SPI CLK
SPI1->CR1 &= ~(1 << 7); //LSBFIRST = 0 => MSB first, then LSB
SPI1->CR1 |= (1 << 8 ) | (1 << 9); //High level SSI and SSM Software control enabled
SPI1->CR1 &= ~(1 << 10); //RXONLY = 0 => Full duplex mode
SPI1->CR1 &= ~(1 << 11); //8-bit
SPI1->CR2 = 0;
}
GPIO settings:

void SpiGPIOConfig(void){
RCC->AHB1ENR |= (1 << 0); //Enable RCC for GPIO_A
GPIOA->MODER |= (2 << 10) | (2 << 12) | (2 << 14) | (1 << 8);
//Alternative function for PA5/6/7 common output for PA4
GPIOA->MODER &= ~(1 << 9); //Push-Pull for PA5/6/7/4 (default)
GPIOA->OSPEEDR |= (3 << 10) | (3 << 12) | (3 << 14) | (3 << 8); //High speed for PA5/6/7/4
GPIOA->AFR[0] |= (5 << 20) | (5 << 24) | (5 << 28); //AF5 (AFRL 0 - 7) on PA5/6/7

}

Transfer:

void SPI_Transmit (uint8_t *data, int size){

//1. Wait for the TXE bit to be set in the registration state
int i = 0;
while(i < size){

while (!((SPI1->SR) & (1 << 1))){}; //Wait for the TXE bit to be set -> This indicates that the buffer is empty
SPI1->DR = data[i]; //Load the data into the data register
i++;
}
while(!((SPI1->SR) & (1 << 1))){}; //Wait for the TXE bit to be set -> This indicates that the buffer is empty
while(((SPI1->SR) & (1 << 7))){}; //Wait for the BSY bit to clear -> This means that the SPIs are not busy with communications

uint8_t temp = SPI1->DR;
temperature = SPI1->SR;

}

Main function:
...
uint8_t RxData[6];
address uint8_t = 0x8f;
while(1){

CS_EN(); // pull the pin low
SPI_Transmit (&address, 1); // send the address
SPI_Receive (RxData, 1); // get 1 byte of data
CS_DIS(); // pull the pin high

Delay_ms(1);
}

If you need to provide something else to find the error, then tell me, I will provide everything you need

liaifat85
Senior III

SPI mode set in the STM32 matches the mode expected by the LSM6DS3. If necessary, try switching to CPOL=0, CPHA=0 (Mode 0) and see if that resolves the issue. If you fear that your sensor itself is faulty, you can cross-check the sensor with an Arduino UNO with the sample code and library given here: https://learn.sparkfun.com/tutorials/lsm6ds3-breakout-hookup-guide/all

If you want to switch to an alternative acelerometer, you can think of HMC6343 Accelerometer. The HMC6343 is a solid-state compass module with tilt compensation. Module. https://www.pcbway.com/project/shareproject/HMC6343_Accelerometer_Module_7ed027c5.html

 .