2023-02-10 01:33 PM
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);
}
2023-02-10 02:35 PM
"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.
2023-02-11 01:35 AM
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.