Skocz do zawartości

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


Pomocna odpowiedź

4 godziny temu, Treker napisał:

@Piotr_73 najlepiej będzie, jeśli założysz osobny temat - pokaż Twój kod, dodaj też przygotowaną mapę bitową oraz zdjęcie "efektu". Może uda się cos doradzić 🙂

Dzięki za zainteresowanie, ale nie wiem czy ciągnąć ten wątek.

Po dwóch dniach bezowocnej walki z hagl w tym temacie, się poddałem i przepisałem funkcję lcd_draw_image, żeby aktualizowała bufor ekranu zamiast wysyłać na spi. Działa tak jak potrzebowałem, a co najważniejsze wiem jak działa 🙂

Jak by się ktoś z podobnym problemem borykał, to mi wyszło tak, jak w załączniku

Z tym, że dane w pliku obrazu bez swapowania bajtów.

 

* LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0

* Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit

 

Pozdrawiam

Piotr

lcd_draw_image.jpg

  • Lubię! 1
  • 7 miesiące później...

@FlasSo witam na forum 🙂 O który dokładnie przykład pytasz? Chodzi Ci o coś z kursu, czy odnosisz się do jakiegoś komentarza z forum?

@FlasSo teraz rozumiem - niestety akurat to nie jest ze sobą powiązane. Mechanizm kolorowania składni na blogu jest niezależny od mechanizmu z CubeIDE.

Jeśli chcesz uzyskać przekreślone zera to możesz zmienić ustawienia edytora i wybrać inny krój: CubeIDE > Window > Preferences > General > Apperance > Colors and Fonts.

  • Lubię! 1
  • 5 miesiące później...

Hej, na wstępie, dzięki za kurs jak na razie( i myślę że to się nie zmieni jest 10 na 10). A przechodząc do problemu, chciałem wyświetlać na wyświetlaczu wartość którą będę zmieniał enkoderem jednak po przekręceniu go ekran robi się cały biały;( pewnie jest jakiś prosty błąd ale nie mogę go znaleźć.
Wrzucam zawartość maina i z góry dzięki za pomoc
 

 lcd_init();
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
  int16_t prev_value =0;
  for (int i = 0; i < 8; i++) {
    hagl_draw_rounded_rectangle(2+i, 2+i, 158-i, 126-i, 8-i, rgb565(0, 0, i*16));
  }





  lcd_copy();
  HAL_Delay(1000);
  while (1)
  {
	  int16_t value = __HAL_TIM_GET_COUNTER(&htim3);
	  if (value != prev_value){
		  wchar_t str[10]; 
		  swprintf(str, sizeof(str) / sizeof(wchar_t), L"%d", value);
		  for (int i = 0; i < 8; i++) {

			  hagl_draw_rounded_rectangle(2+i, 2+i, 158-i, 126-i, 8-i, rgb565(0, 0, i*16));

		    }
		  hagl_put_text(str, 40, 55, YELLOW, font6x9);
		  while (lcd_is_busy()) {}
		  	  		  lcd_copy();
	  }

 

@Gabmi witam na forum 🙂 Cieszę się, że kurs oceniasz na 10 💘 Czy wkleiłeś cały kod main, bo zmienna prev_value nie jest chyba(?) nigdy aktualizowana?

  • 1 miesiąc później...
(edytowany)

Tak patrz na porównanie prędkości wyświetlania prostokątów na ekranie wyświetlacza i wynik bardzo zależy od tego czy resetuję program i wyświetlacz przez wyłączenie zasilania, czy przez przycisk reset w Nocleo. Resetowanie przyciskiem pokazuje nawet że kolorowa tęcza prostokątów wyświetlana pierwotnym niezoptymalizowanym programem jest wyświetlana szybciej niż te białe kwadraty. Natomiast gdy wyłączę i załączę zasilanie - wynik obserwacji jest zgodny z oczekiwaniami. Myślę że przyczyna tkwi w niepełnym resecie wyświetlacza przez funkcję lcd_init()

void lcd_init(void)
{
  int i;
  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET); //LCD Reset
  HAL_Delay(100);
  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET); //RCD Reset off
  HAL_Delay(100);
  for (i = 0; i < sizeof(init_table) / sizeof(uint16_t); i++) { //Sends initial display parameters.
    lcd_send(init_table[i]);
  }
  HAL_Delay(200);
  lcd_cmd(ST7735S_SLPOUT); //Display wakeup
  HAL_Delay(120);
  lcd_cmd(ST7735S_DISPON); //Display ON
}

W pierwszej linii mamy reset sprzętowy linią reset, ale wygląda na to, że ten reset nie czyści pamięci wyświetlacza i obrazek tęczy pozostaje w pamięci dopóki jest zasilanie. Trzeba by dodać do funkcji lcd_init wypełnienie całości czarnym kolorem, albo wartościami random, tak jak to było przy pierwszym uruchomieniu funkcji lcd_init i wtedy wyniki nie będą zależeć od rodzaju resetu.

void lcd_init(void)
{
  int i;
  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET); //LCD Reset
  HAL_Delay(100);
  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET); //RCD Reset off
  HAL_Delay(100);
  for (i = 0; i < sizeof(init_table) / sizeof(uint16_t); i++) { //Sends initial display parameters.
    lcd_send(init_table[i]);
  }
  HAL_Delay(200);
  lcd_fill_box(0,0,160,128,BLACK);
  lcd_cmd(ST7735S_SLPOUT); //Display wakeup
  HAL_Delay(120);
  lcd_cmd(ST7735S_DISPON); //Display ON
}

Po dodaniu komendy lcd_fill_box(....), która czyści ekran kolorem czarnym, obserwację są niezależne od sposobu resetowania.

Edytowano przez aimeiz
  • Lubię! 1

Bardzo fajny rozdział kursu. Dużo zagadnień poruszonych.

W niektórych sytuacjach na wyświetlaczu większość zawartości jest stała a zmieniają się tylko fragmenty. Przykładem może być praca domowa - pomiar natężenia oświetlenia.

Możemy stworzyć to co stałe i wysłać na wyświetlacz np. jakąś szatę graficzną, tytuł, etc a następnie wysyłać wprost na ekran tylko to co się zmienia. Wtedy bufor RAM na ekran nie musi być taki duży, gdyż ta stała część może być wysłana bez buforowania, a na obszar zmienny czyli ten wskaźnik kreskowy, zarezerwować znacznie mniejszy bufor ram. Czy to ma sens i da się tak zrobić?

Bawiłem się kiedyś wyświetlaczem Nokia 5110. Wszystkie dostępne biblioteki używały pełnego bufora ekranu. Żeby cokolwiek zmienić na ekranie trzeba było wyczyścić i wyświetlić cały ekran na nowo co powodowało miganie. Na wyświetlaczach TFT było łatwiej, bo mają własną pamięć, którą można adresować selektywnie a w niektórych nawet odczytać aktualny stan piksela.

 

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...