cancel
Showing results for 
Search instead for 
Did you mean: 

I want to develop a C program on the STM32F303 board that uses the SPI interface where the microcontroller is the master and the L3GD20 gyroscope is the slave: I want to perform a transmission to ask the gyroscope to provide me with the x, y, z coordinate

FPalo.1
Associate II

Considering that the gyroscope's chip select is the PE3 pin, how should I do this? The program below doesn't work

#include <stm32f30x.h>

void GPIO_Config();

void SPI_Config();

uint8_t L3GD20_Read(uint8_t reg);

void L3GD20_Write(uint8_t reg, uint8_t data);

void L3GD20_Init();

void L3GD20_CS_Low();

void L3GD20_CS_High();

int16_t x,y,z;

int main(void){

// Inizializzazione del sistema e delle periferiche

GPIO_Config();

SPI_Config();

L3GD20_Init();

while (1)

{

  // Attivazione del giroscopio

      L3GD20_CS_Low();

  // Trasmissione dell'indirizzo del registro x per la lettura delle coordinate x

  SPI1->DR = 0x28 | 0x80;

  while (!(SPI1->SR & SPI_SR_TXE));

  while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);

  x = ((int16_t)(L3GD20_Read(0x29) << 8)) | L3GD20_Read(0x28);

       

  // Trasmissione dell'indirizzo del registro y per la lettura delle coordinate y

  SPI1->DR = 0x2A | 0x80;

  while (!(SPI1->SR & SPI_SR_TXE));

  while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);

  y = ((int16_t)(L3GD20_Read(0x2B) << 8)) | L3GD20_Read(0x2A);

  // Trasmissione dell'indirizzo del registro z per la lettura delle coordinate z

  SPI1->DR = 0x2C | 0x80;

  while (!(SPI1->SR & SPI_SR_TXE));

  while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);

  z = ((int16_t)(L3GD20_Read(0x2D) << 8)) | L3GD20_Read(0x2C);

  // Disattivazione del giroscopio

  L3GD20_CS_High();

}

}

void GPIO_Config(){

//Abilitare clock su periferiche GPIOA e GPIOE

RCC->AHBENR |= RCC_AHBENR_GPIOEEN;

RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

//Impostare PE3 (Chip Select) come output

GPIOE->MODER |= GPIO_MODER_MODER3_0;

//Impostare PA5, PA6, PA7 rispettivamente come SCK, MISO, MOSI

GPIOA->AFR[0] |= (5<<20) | (5<<24) | (5<<28);

}

void SPI_Config(){

// Abilitare clock su periferica SPI1

RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

// Configurare SPI1 in modalità master e imposta il baud rate prescaler di 8

    SPI1->CR1 = 0;

SPI1->CR1 |= SPI_CR1_MSTR;

    SPI1->CR1 |= SPI_CR1_BR_1;

// Configurare modalità di lavoro del bus SPI: CPOL=0, CPHA=0

SPI1->CR1 &= ~SPI_CR1_CPOL;

SPI1->CR1 &= ~SPI_CR1_CPHA;

// Abilitare gestione software del chip select (NSS)

SPI1->CR1 |= SPI_CR1_SSM;

SPI1->CR1 |= SPI_CR1_SSI;

    SPI1->CR2 = 0;

    SPI1->CR2 |= SPI_CR2_DS_3;

     

// Abilitare periferica SPI1

SPI1->CR1 |= SPI_CR1_SPE;

}

uint8_t L3GD20_Read(uint8_t reg){

  uint8_t data;

  // Trasmissione del registro da leggere

  SPI2->DR = reg;

  while (!(SPI1->SR & SPI_SR_TXE));

  while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);

  // Ricezione dei dati dal giroscopio

  uint8_t dummy_read = SPI1->DR;

  while (!(SPI1->SR & SPI_SR_RXNE));

  data = SPI1->DR;

  return data;

}

void L3GD20_Write(uint8_t reg, uint8_t data){

// Trasmissione dell'indirizzo del registro 'reg' per la scrittura

  SPI2->DR = reg;

  while (!(SPI1->SR & SPI_SR_TXE));

  while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);

// Trasmissione del valore 'data' da scrivere nel registro 'reg'

  SPI2->DR = data;

  while (!(SPI1->SR & SPI_SR_TXE));

  while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);

}

void L3GD20_Init(){

// Impostazione dei bit Xen, Yen, Zen e PD per accendere il giroscopio e attivare i 3 assi

L3GD20_Write(0x20, 0x0F);

}

void L3GD20_CS_Low() {

GPIOE->BSRR = (1 << (3 + 16));

}

void L3GD20_CS_High() {

GPIOE->BSRR = (1 << 3);

}

2 REPLIES 2
Bob S
Principal

"doesn't work" is pretty generic and non-helpful.

What about that code doesn't work? Can you read data from the gyro? Are you having trouble converting the data to whatever units you want? What have you tried so far to fix it?

If you have trouble with the SPI interface, double-check the register settings.

You might even try (gasp) creating a version of your program using CubeMX and use the HAL_SPI_Transmit() and/or HAL_SPI_Transmit_Receive() type functions and see if THAT works. If so, compare the SPI settings and how they read/write with your code.

FPalo.1
Associate II

The program compiles but when I start the debugging and it arrives to " x = ((int16_t)(L3GD20_Read(0x29) << 8)) | L3GD20_Read(0x28);" , it jumps to the function L3GD20_Read and the loop "while (!(SPI1->SR & SPI_SR_RXNE));" is repeated endlessly, so the flag RXNE hasn't set to 1 and I don't understand why.