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 coord
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);
}