Ich habe seit einiger Zeit versucht, den SPI1 auf dem STM32F103C8 ( Blue Pill Board) zum Laufen zu bringen . Während ich gerade erst anfange, ARM zu lernen, versuche ich einfach, Daten in ein 74HC595-Schieberegister zu verschieben und es zu verriegeln, um ein Byte LEDs zu beleuchten. Ich lese keine Daten zurück, daher habe ich nur MOSI-, SCK- und SS-Leitungen.
Zuerst bekam ich nichts heraus, aber als ich einige Online-Beispiele las, konnte ich diese ersten Probleme beheben, um die Kommunikation in Gang zu bringen (ich musste die GPIOA-Pins richtig einstellen und die Software SS einstellen).
Das Hauptproblem im Moment ist, dass wenn ich nicht in allen Leitungen Pull-up-Widerstände (MOSI, SCK und SS) einbeziehe, der Mikrocontroller in keiner Leitung etwas ausgibt (mit einem Oszilloskop überprüft). Darüber hinaus ist die Anstiegszeit der Impulse nach dem Hinzufügen von Pull-up-Widerständen sehr langsam, sodass ich keine zu hohe Frequenz verwenden kann (mit 10-kΩ-Pull-up-Widerständen bin ich auf ca. 250 kHz SCK und Schalten beschränkt bis 330 Ω ca. 4 MHz). Ich arbeite an einem Steckbrett, aber selbst dann mit AVR und unordentlicherer Verkabelung konnte ich einen 4-MHz-SPI ohne zusätzliche Widerstände problemlos zum Laufen bringen, und die Wellenformen waren sauberer.
Hier sind zwei Bilder (Entschuldigung für den miserablen Zustand meines Oszilloskopbildschirms), die das Byte 0b01110010 mit einem 250-kHz-Takt übertragen. Die obere Spur ist SCK und die untere ist MOSI. Das erste Bild zeigt 10-kΩ-Pull-up-Widerstände und das zweite 330-Ω-Pull-up-Widerstände, die die Wellenformen viel schöner machen (aber nicht benötigt werden sollten).
Ich würde mich über Hilfe freuen, um herauszufinden, was los ist.
Die relevanten Teile meines Codes sind:
#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;
Antworten:
Sie sollten den Wert der Pins, die Sie ändern, zurücksetzen, bevor Sie die Bits setzen.
Der Rücksetzwert von GPIOA_CRL ist 0x4444 4444. Jeder Pin wird also mit 0b0100 initialisiert. Wenn Sie | = 0b0011 ausführen, erhalten Sie 0b0111, einen Open-Drain-Ausgang. Dasselbe gilt für 0b1011 und wird zu 0b1111. Dies ist ein offener Drain mit alternativer Funktion.
Sie müssen also so etwas tun:
quelle