Sto provando a far funzionare correttamente SPI1 su STM32F103C8 ( scheda Blue Pill ) da qualche tempo. Mentre sto appena iniziando a studiare ARM, sto semplicemente cercando di spostare i dati in un registro a scorrimento 74HC595 e bloccarli per illuminare un byte di LED. Non sto leggendo alcun dato, quindi ho solo linee MOSI, SCK e SS.
All'inizio non stavo ottenendo nulla, ma leggendo alcuni esempi online ho potuto risolvere questi primi problemi per avviare la comunicazione (avevo bisogno di impostare correttamente i pin GPIOA e impostare il software SS).
Il problema principale in questo momento è che se non includo resistenze di pull-up su tutte le linee (MOSI, SCK e SS) il microcontrollore non emette nulla su nessuna linea (controllato con un ambito). Inoltre, dopo aver aggiunto resistori pull-up, il tempo di salita sugli impulsi è molto lento, quindi non posso usare una frequenza troppo alta (con resistori pull-up da 10 kΩ ho un limite di circa 250 kHz SCK e la commutazione a 330 Ω circa 4 MHz). Sto lavorando su una breadboard, ma anche in questo caso con AVR e cavi più corposi ho potuto ottenere un SPI a 4 MHz funzionante senza problemi senza resistori aggiunti e le forme d'onda erano più pulite.
Ecco due immagini (mi dispiace per lo stato abissale della mia schermata dell'oscilloscopio) che trasmettono il byte 0b01110010 a un clock di 250 kHz. La traccia superiore è SCK e la parte inferiore è MOSI. La prima immagine è con resistenze pull-up da 10 kΩ e la seconda con resistenze pull-up da 330 Ω che rendono le forme d'onda molto più belle (ma non dovrebbero essere necessarie).
Apprezzerei un po 'di aiuto per capire cosa sta succedendo.
Le parti rilevanti del mio codice sono:
#define SS_LOW GPIOA->BSRR |= 1 << 4 + 16;
#define SS_HIGH GPIOA->BSRR |= 1 << 4;
// SPI GPIO configuration
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRL |= 0b0011 << 4 * 4; // Set pin A4 as PP out 50mHz for SS
GPIOA->CRL |= 0b1011 << 5 * 4; // Set pin A5 AltFunc PP out 50mHz for SCK
GPIOA->CRL |= 0b1011 << 7 * 4; // Set pin A7 AltFunc PP out 50mHz for MOSI
SS_HIGH;
// SPI1 configuration
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Enable SPI1 clock
SPI1->CR1 |= SPI_CR1_SSM; // Software SS
SPI1->CR1 |= SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_BR_0; // Set prescaler
SPI1->CR1 |= SPI_CR1_BR_1;
SPI1->CR1 |= SPI_CR1_BR_2;
SPI1->CR1 |= SPI_CR1_MSTR; // Master mode
SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI
// Transmit byte
SS_LOW;
SPI1->DR = 0b01110010;
while(!(SPI1->SR & SPI_SR_TXE));
while(SPI1->SR & SPI_SR_BSY);
SS_HIGH;