Witam,
Mam pewnien problem ze zrozumieniem SPI w STM32F0 (dokładnie STM32F030C8T6).
Mianowicie, przy takiej konfiguracji:
oraz chcąc wysłać 1 bajt dancych za pomocą tego kodu:
mam połowiczny sukces.
Moje pytania są następujące:
1) Dlaczego gdy wysyłam do slave np 0x82 to w rejestrze FTLVL mam 0x02 (czyli tak jak bym miał 2 bajty w TxFIFO a nie jeden) kiedy wysylam jeden bajt?( widzę to od razu po wykonaniu załadowania danych do rejestru przesuwnego DR). Przez to w RxFIFO pierwszy bajt (LSB) są jakieś śmieci (np. 0x00 lub 0x01) a w kolejnym bajcie mam już prawidłową wartość jaką powinienem dostać z układu (np. 0x20)?
W inicjalizacji mam, że bufor "dzieli się na 4x8 bitów",
2) Jak puszczam by bajty odebrane przesyłał mi na terminal to widzę, że na przemian odbiera prawidłową wartość a następnie śmieci (tak z 5 razy) po czym wysyła już same śmieci. (Gdy zatrzymuje debugowanie to widzę, że rejestr przesuwny jest pusty DR = 0x0 ale podejrzewam, że po prostu nie odczytuje wszystkich rzeczy z RxFIFO przez co on się przepełnia i wywala błędy),
3) Jak to jest z tym nSS bo go kompletnie nie rozumiem?!
można sprzętowo/programowo uruchamiać slave za pomocą nSS czy trzeba wykorzystywać GPIO? Czyli zamiast zaprzęgać f. alternatywną dać zwykłe GPIO typu push-pull?! Z tego co zrozumiałem to on się przydaje gdy STM32F0 staje się slavem, no ale mogłem źle zrozumieć.
Gdzieś tutaj na forum podpatrzyłem kombinację z włączaniem/wyłączaniem SPI ale to nie jest moim zdaniem dobry pomysł bo w nocie jest napisane że po wył SPI odłącza się od logiki GPIO i (moim zdaniem) mamy stan Hi-Z. Może wtedy warto dać pull-up wewnętrzny? (jeżeli chodzi o połączenie maste <-> slave to full duplex, bez zewnętrznych rezystorów (pull-up/down) na magistrali. (w ksążce Marka Galewskiego zobaczyłem że na linii SCK ma podłączony pull-up)
Byłbym bardzo wdzięczny za pomoc, ponieważ sam od niedawna zaczynam ogarniać STM...
Mam pewnien problem ze zrozumieniem SPI w STM32F0 (dokładnie STM32F030C8T6).
Mianowicie, przy takiej konfiguracji:
void SPI_Set(void)
{
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // wlaczenie zegara dla SPI1
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //wlaczenie zegara dla portu A (ponowne)
GPIOA->MODER |= (GPIO_MODER_MODER4_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1); //GPIO jako funkcje alternatywne
GPIOA->OSPEEDR |= (GPIO_OSPEEDR_OSPEEDR4_0 |GPIO_OSPEEDR_OSPEEDR5_0 | GPIO_OSPEEDR_OSPEEDR6_0 | GPIO_OSPEEDR_OSPEEDR7_0); // GPIO œrednia predkosc
GPIOA->AFR[0] &= ~(GPIO_AFRL_AFR4 | GPIO_AFRL_AFR5 | GPIO_AFRL_AFR6 | GPIO_AFRL_AFR7); // funkcja alternatywna jako SPI1
//Ustawienia SPI1
SPI1->CR2 |= (SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2 | SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_NSSP | SPI_CR2_FRXTH | SPI_CR2_SSOE); // DS[0:4]= 8 bitów wysyla; wywolanie przerwania kiedy odbierzemy/zapelnimy rejestr DR; ustawienie flagi na SPI1->SR gdy FRLCL bedzie zajmowac conajmniej 1/4 buffora
SPI1->CR1 |= (SPI_CR1_BR_1 | SPI_CR1_MSTR );// | SPI_CR1_SSM | SPI_CR1_SSI //BR = F_PCLK/8 ; STM jako Master; nSS jako programowy a stan na wyjsciu ustawiany jest bitem SSI;
SPI1->CR1 &= ~(SPI_CR1_CPOL | SPI_CR1_CPHA | SPI_CR1_LSBFIRST);//CPOL = 0 i CPHA = 0; wysylanie od MSB
SPI1->CR1 &= ~(SPI_CR1_SPE);//wlaczenie SPI
//NVIC_EnableIRQ(SPI1_IRQn);//wlaczenie przerwania SPI
}
oraz chcąc wysłać 1 bajt dancych za pomocą tego kodu:
uint8_t SPI_Receive_Data (uint8_t data)
{
uint8_t tmp;
tmp = data;
SPI1->DR = tmp;//wprowadza do rejestru przesownego 'data'
SPI1->CR1 |= (SPI_CR1_SPE);//wlaczenie spi
//while(!(SPI1->SR & SPI_SR_TXE));//sprawdza czy buffor TXFIFO jest pelen
while((SPI1->SR & SPI_SR_FTLVL_0));
while((SPI1->SR & SPI_SR_BSY));
SPI1->CR1 &= ~(SPI_CR1_SPE);//wylaczenie spi
tmp = (SPI1->DR);
return tmp;
}mam połowiczny sukces.
Moje pytania są następujące:
1) Dlaczego gdy wysyłam do slave np 0x82 to w rejestrze FTLVL mam 0x02 (czyli tak jak bym miał 2 bajty w TxFIFO a nie jeden) kiedy wysylam jeden bajt?( widzę to od razu po wykonaniu załadowania danych do rejestru przesuwnego DR). Przez to w RxFIFO pierwszy bajt (LSB) są jakieś śmieci (np. 0x00 lub 0x01) a w kolejnym bajcie mam już prawidłową wartość jaką powinienem dostać z układu (np. 0x20)?
W inicjalizacji mam, że bufor "dzieli się na 4x8 bitów",
2) Jak puszczam by bajty odebrane przesyłał mi na terminal to widzę, że na przemian odbiera prawidłową wartość a następnie śmieci (tak z 5 razy) po czym wysyła już same śmieci. (Gdy zatrzymuje debugowanie to widzę, że rejestr przesuwny jest pusty DR = 0x0 ale podejrzewam, że po prostu nie odczytuje wszystkich rzeczy z RxFIFO przez co on się przepełnia i wywala błędy),
3) Jak to jest z tym nSS bo go kompletnie nie rozumiem?!
Byłbym bardzo wdzięczny za pomoc, ponieważ sam od niedawna zaczynam ogarniać STM...