Ich versuche, den grundlegenden SPI-Betrieb auf einem STM32F107VC-Chip mit dem WaveShare Port107-Entwicklungsboard zum Laufen zu bringen. Ich versuche, SPI1 zu initialisieren, das sich auf PA4-PA7 befindet.
Ich versuche einen einfachen Loopback-Test, also ist MISO direkt mit MOSI verbunden. Ich habe auch ein Oszilloskop an NSS und SCK angeschlossen.
Unten ist mein Code:
// Clock configuration
RCC->APB2ENR |= 1; // Alternate Function Clock Enable
RCC->APB2ENR |= 1<<2; // Enable clock to Port A.
RCC->APB2ENR |= 1<<12; // Enable clock for SPI1.
// Pin configuration (no remapping)
// Output = AF PushPull 50MHz.
// Input = Active Pullup/Pulldown
// I have tried NSS as AFPuP, Active Pullup/Pulldown, GPIO output etc...
// NSS (PA4) = input, CLK (PA5) = output, MISO (PA6) = input, MOSI (PA7) = output
GPIOA->CRL = 0xB8B80000;
// General SPI configuration
SPI1->CR1 = 0;
SPI1->CR1 |= 7<<3; // Lowest frequency.
SPI1->CR1 &= ~(1<<0); // Clock phase. 1st clock transition starts data capture
SPI1->CR1 |= 1<<1; // Clock polarity. High when idle.
SPI1->CR1 &= ~(1<<11); // Use 8 bit data
SPI1->CR1 |= 1<<7; // LSB transmitted first.
//SPI1->CR1 |= 1<<9; // Software slave management
//SPI1->CR1 |= 1<<8 // Software NSS bit high
SPI1->CR1 |= 1<<2; // Master device.
SPI1->CR1 &= ~(1<<10); // Use both RX and TX
SPI1->CR1 &= ~(3<<12); // No CRC
SPI1->CR1 &= ~(1<<15); // 2-line unidirectional mode
SPI1->CR2 = 0; // Polling mode (no interrupts)
SPI1->CR1 |= 1<<6; // Enable SPI1.
Um nun den Loopback-Test durchzuführen, sende ich ein Byte und lese dann das Byte zurück (ich habe die Verwendung eines 8-Bit-Schieberegisters konfiguriert).
void loopback(unsigned char byte)
{
GPIOA->BSRR &= ~(1<<4); // !NSS line set to low (active) state. I have
// also attempted to use GPIOA->ODR and
// also attempted software NSS mode.
// while ((SPI1->SR & (1 << 7)) != 0 ); // Wait for BUSY to clear. not using.
while (!(SPI1->SR & (1 << 1))); // Wait TXE (Transmit buffer empty)
SPI1->DR = byte;
// read it back
unsigned char readByte = ReadByte();
if (byte == readByte)
{
// ... Test passed!
}
GPIOA->BSRR |= 1<<4; //!NSS set high. (unactive state).
}
unsigned char ReadByte(void)
{
while (!(SPI1->SR & (1 << 0))); // Wait RXNE (Receive not empty (we have data))
unsigned char readByte = SPI1->DR;
return readByte;
}
Überwachen von CLK und NSS (und MISO/MOSI) mit einem Oszilloskop, wenn NSS in seinen aktiven Low-Zustand geht, oszilliert keine Taktleitung. Selbst wenn eine Übertragung versucht wird, werden die Bits im Datenregister gesetzt, aber ich glaube nicht, dass sie aus DR herausgeschoben werden, da RXNE niemals hoch geht (was sinnvoll ist, da keine Taktleitung aktiv ist).
Könnte mir jemand sagen, warum die clk-Leitung niemals oszilliert? Ist meine Konfig falsch?
Grüße
Entkommentieren Sie Zeilen, die SSM (CR1 Bit 9) ermöglichen, die manuelle Slave-Auswahl zu verwenden.
SPI1->CR1 |= SPI_CR1_SSM; //disable automatic SS
Tut
Venny
Venny
Ospho
Ospho