LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

Komunikacja mikrokontrolerów STM32 z pamięciami DataFlash

Na listingu 5 zamieszczono funkcję kasującą stronę w pamięci erasePage(). Określenie zajętości układu rozwiązano poprzez sprawdzanie zawartości rejestru statusu. Jednak aby nie wstrzymywać pracy całego systemu mikroprocesorowego na niekrótki przecież czas kilkudziesięciu milisekund, użyty został timer SysTick. Funkcja erasePage() tak konfiguruje timer, żeby ten po upływie 35 ms wygenerował przerwanie. Obsługa przerwania, zamieszczona na listingu 6, oddaje muteks oraz wyłącza przerwanie.

 

List. 6. Funkcja obsługi timera SysTick

void SysTick_Handler(void)
{
    /* Wyłączenie timera oraz jego przerwania */
    SysTick->CTRL = (0<

 

Rys. 8. Ciągły odczyt pamięci bez użycia bufora

Rys. 8. Ciągły odczyt pamięci bez użycia bufora

 

 

Ciągły odczyt bez użycia bufora

Zasadę działania ciągłego odczytu pamięci bez użycia bufora przedstawiono na rysunku 8. Z rysunku wynika, należy podać adres początkowy bajta w stronie, a odczyt następuje już przez całą przestrzeń adresową. Po osiągnięciu ostatniego bajta w ostatniej stronie układ pamięci automatycznie rozpoczyna odczyt od początku pierwszej strony. Jak już wspomniano, domyślny rozmiar strony wynosi 528 bajtów.

 

Rys. 9. Adresowanie pierwszego do odczytu bajtu w stronie

Rys. 9. Adresowanie pierwszego do odczytu bajtu w stronie

 

 

Dla tego przypadku adresowanie jest następujące. W pierwszej kolejności należy wysłać do układu pamięci bajt komendy, dla ciągłego odczytu bez bufora będzie to wartość 0xE8, a zaraz po nim trzy bajty adresowe. Podział bajtów adresowych na adres strony oraz na adres bajta w stronie zamieszczono na rysunku 9, natomiast całą funkcję continousRead(), która inicjuje ciągły odczyt przedstawia listing 7. W argumentach do funkcji należy przekazać adres strony, adres bajta w stronie oraz liczbę bajtów, jakie mają zostać odczytane.

 

List. 7. Funkcja rozpoczynająca ciągły odczyt pamięci

void continousRead(uint16_t pageAddress, uint16_t byteAddress, uint16_t nofBytesToRead)
{
    /* sprawdzanie muteksa */
    while(SPI_InUse);
    /* "weź" muteks */
    SPI_InUse = 0x11;
    SPI_Cmd(SPI1, DISABLE);
    SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
    SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
    /* Nof_Bytes_To_TxRx = nofBytesToRead + komenda + 3xAdres + 4 bajty nieznaczące */
    Nof_Bytes_To_TxRx = nofBytesToRead + 8;
    /* Komenda "continuous read" */
    TxBuf[0] = 0xE8;
    /* Starsze 7 bitów adresu strony */
    TxBuf[1] = (uint8_t) pageAddress>>6;
    /* Pozostałe (młodsze) 6 bitów adresu strony,
     * ale wyrównane do lewej strony + dwa starsze bity
     * adresu bajta w stronie*/
    TxBuf[2] = ((uint8_t) pageAddress<<2) | ((uint8_t) byteAddress>>8);
    /* Młodsze 8 bitów adresu bajta w stronie */
    TxBuf[3] = (uint8_t) byteAddress;
    SPI_Cmd(SPI1, ENABLE);
    GPIO_SetBits(GPIOA, CS);
    /* CS w stan niski */
    GPIO_ResetBits(GPIOA, CS);
}

 

Bufor odbiorczy RxBuf[] powinien być kopiowany dopiero od bajta o indeksie 8, a to dlatego, że pomiędzy ostatnim bajtem adresowym wysłanym do układu pamięci, a pierwszym odebranym bajtem z danymi muszą wystąpić cztery bajty nieznaczące. Zatem mamy „do przeskoczenia”: komendę (czyli pierwszy bajt), trzy bajty adresowe oraz cztery bajty nieznaczące.