Skocz do zawartości

Kurs STM32L4 – #11 – kolorowy wyświetlacz TFT (SPI)


Pomocna odpowiedź

Nie mam w tej chwili możliwości fizycznego przetestowania układu, ale przeglądając kod biblioteki wygląda na to że jak zwykle kolega @gtx ma rację 🙂

Wartość HAL_SPI_STATE_BUSY jest używana tylko podczas inicjalizacji modułu, więc w naszym przykładzie powinniśmy używać HAL_SPI_STATE_BUSY_TX zamiast niej.

Chociaż przyznam, że wersja z porównywaniem do HAL_SPI_STATE_READY, czyli funkcja lcd_is_busy2 bardziej mi się podoba, zadziała również przy odbieraniu danych, albo komunikacji dwukierunkowej. Nie wykorzystamy takich możliwości w przypadku naszego wyświetlacza, ale może warto zastosować bardziej uniwersalne rozwiązanie.

 

Edytowano przez Elvis
  • Lubię! 2
Link do komentarza
Share on other sites

Dnia 11.01.2023 o 19:59, gtx napisał:

Obiecuję, że to już ostatni raz.

@gtx każda informacja zwrotna jest potrzebna, cieszę się, że tak skrupulatnie wykonujesz kolejne ćwiczenia z kursu. Wiele osób sprawdzało kurs, wiele osób się z niego uczyło, a Tobie i tak udało się jeszcze wyłapać kilka rzeczy. Każdy błąd chętnie naprawimy. A za Twoją spostrzegawczość i aktywność należy Ci się jakaś specjalna nagroda 😉 Wyślij do mnie w prywatnej wiadomości numer telefonu i adres dla kuriera lub kod paczkomatu - z przyjemnością nadam paczkę z kubkiem i innymi gadżetami 🚀

  • Lubię! 1
Link do komentarza
Share on other sites

Panowie @Treker @Elvis za to podpowiedzcie mi proszę taką rzecz. Mam bibliotekę HAGL, ale nie chcę jej zmieniać - może w przyszłości ją przeinstaluję, zapomnę, że coś zmieniłem, itd. Natomiast nie podoba mi się w niej to, że dodaje czarne tło pod literkami. Żeby tego uniknąć zmieniłem jedną linijkę w hagl_put_char:

uint8_t hagl_put_char(void const *surface, wchar_t code, int16_t x0, int16_t y0, color_t color, const uint8_t *font)
{
    uint8_t set, status;
    color_t buffer[HAGL_CHAR_BUFFER_SIZE];
    hagl_bitmap_t bitmap;
    fontx_glyph_t glyph;

    status = fontx_glyph(&glyph, code, font);

    if (0 != status) {
        return 0;
    }

    bitmap.width = glyph.width,
    bitmap.height = glyph.height,
    bitmap.depth = DISPLAY_DEPTH,

    bitmap_init(&bitmap, (uint8_t *)buffer);

    color_t *ptr = (color_t *) bitmap.buffer;

    for (uint8_t y = 0; y < glyph.height; y++) {
        for (uint8_t x = 0; x < glyph.width; x++) {
            set = *(glyph.buffer + x / 8) & (0x80 >> (x % 8));
            if (set) {
                *(ptr++) = color;
            } else {
                *(ptr++) = lcd_get_pixel(x0+x,y0+y); //INVISIVLE BACKGROUND
            }
        }
        glyph.buffer += glyph.pitch;
    }

    hagl_blit(surface, x0, y0, &bitmap);

    return bitmap.width;
}

gdzie:

uint16_t lcd_get_pixel(int x, int y)
{
	return frame_buffer[x+y*LCD_WIDTH];
}

i umieściłem ją w swojej bibliotece. Problem jest oczywiście taki, że C nie pozwala na definiowanie dwóch takich samych funkcji, zresztą przeciążanie z C++ też by chyba nie pomogło. Jedyne co przyszło mi do głowy (i zadziałało) to dodanie atrybutu  __attribute__((weak)) w pliku char.h za prototypem funkcji hagl_put_char. Ale ciągle jest to zmiana biblioteki. Czy jest jakiś inny, sprytny sposób na to?

 

Link do komentarza
Share on other sites

Chyba najprościej jest wykorzystać git-a do utworzenia nowej gałęzi (branch) i w niej dodać wszystkie potrzebne zmiany. W przyszłości po prostu użyjesz "git rebase" i jeśli w głównej gałęzi biblioteki nie będzie drastycznych zmian, wszystko zadziała zgodnie z oczekiwaniami.

Użycie modyfikatora weak, albo inne sztuczki w kodzie to chyba niezbyt dobry kierunek. Pewnie zadziała, ale jak za jakiś czas dodasz kolejną zmianę to opanowanie kodu będzie bardzo trudne. Git takie problemy rozwiązuje niejako z automatu.

Natomiast jako ciekawostkę można poczytać o opcji gcc -Wl,--wrap (https://github.com/sadiquealy/GCC_Mocking). Za jej pomocą można byłoby pewnie osiągnąć to o co pytałeś, czyli zastąpić funkcję inną bez zmiany kodu biblioteki. Ale to mechanizm przeznaczony do testowania i raczej nie ułatwi późniejszych zmian w programie.

Edytowano przez Elvis
  • Lubię! 2
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  lcd_init();
  hagl_backend_t *display = hagl_init();
  metaballs_init();
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	metaballs_animate();
	metaballs_render(display);
	lcd_copy();
  }  
  /* USER CODE END 3 */

Można nawet schować linijkę while (lcd_is_busy()) {}

do środka ciała funkcji lcd_copy()  🙂

Link do komentarza
Share on other sites

19 godzin temu, dudoxx napisał:
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  lcd_init();
  hagl_backend_t *display = hagl_init();
  metaballs_init();
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	metaballs_animate();
	metaballs_render(display);
	lcd_copy();
  }  
  /* USER CODE END 3 */

Można nawet schować linijkę while (lcd_is_busy()) {}

do środka ciała funkcji lcd_copy()  🙂

No nie do końca. Jeśli wysyłasz dane po DMA, to w ten sposób możesz zacząć nadpisywać bufor podczas wysyłania poprzednich danych do LCD i dostaniesz krzaczki jak ja w jednym z postów powyżej. Rzeczywiście tego efektu nie było widać w metaballs, ale w innych projektach możesz mieć problem.

  • Lubię! 1
Link do komentarza
Share on other sites

Racja, dzięki za uwagę 🙂

Chociaż jak nie wróce z lcd_copy() to nie bedą się generować nowe dane do bufora, więc chyba potrzebowałbym szerszego wyjaśnienia

Link do komentarza
Share on other sites

Wyobraź sobie taką sytuację:

1. Wgrywasz zdjęcie kotów do bufora (ja tak zrobiłem 😉 )

2. Rozpoczynasz od razu w lcd_copy kopiowanie danych do bufora po DMA.

3. DMA w tle wysyła dane, doszedł powiedzmy do połowy. Zwraca sterowanie do programu głównego, możesz wykonywać inne operacje.

4. Nie czekasz, zmieniasz natychmiast bufor na zdjęcie psów.

5. DMA kopiuje w tle drugą połowę z bufora, teraz ma tam psy.

6. Dostajesz połowę wyświetlacza kotów i połowę psów.

Dlatego trzeba czekać przed zmianą bufora.

Link do komentarza
Share on other sites

To nie do końca jest sens używać DMA, bo o ile dobrze rozumiem DMA jest właśnie po to, żeby uwolnić procesor 🙂 Jeśli masz lcd_busy na końcu lcd_copy to nie masz żadnej różnicy pomiędzy Transmit a Transmit_DMA.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

25 minut temu, gtx napisał:

To nie do końca jest sens używać DMA, bo o ile dobrze rozumiem DMA jest właśnie po to, żeby uwolnić procesor 🙂 Jeśli masz lcd_busy na końcu lcd_copy to nie masz żadnej różnicy pomiędzy Transmit a Transmit_DMA.

Myślę, że mimo wszystko z użyciem DMA jest to o wiele szybsze natomiast pokracznie to użyłem blokując główną pętle 😛

Link do komentarza
Share on other sites

20 godzin temu, Pele_Wkurzony napisał:

Ile taki wyświetlacz pobiera prądu w najgorszym przypadku? Ile możemy pobierać z zasilania stm i co jeżeli przekroczymy tą wartość?

@Pele_Wkurzony niestety producent tego nie podaje, a nie mam pod ręką tego wyświetlacza, aby dokonać pomiaru, jednak spokojnie - zapas tam na pewno jest. Jeśli chodzi Ci o pobieranie prądu z płytki Nucleo (a nie z samego mikrokontrolera) to wszystko zależy od sposobu zasilania płytki. Jest to dokładnie rozpisane w tzw. user manualu płytki Nucleo. Jeśli chodzi o zasilani z pinów 3,3 V to limitem jest stabilizator U4, który łącznie może dostarczyć 500 mA.

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.