Skocz do zawartości

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


Pomocna odpowiedź

Dzięki za kolejny odcinek. Czuję że naprawdę dużo się nauczyłem. Mam kilka pytań:

1. Pierwsza rzecz jaką spróbowałem zrobić to animacje używające funkcji trygonometrycznych do wyznaczenia koloru piksela. Szybko okazało się, że jest to masakrycznie wolne, co mnie zaskoczyło, bo pamiętałem, że STM32L4 ma FPU. W końcu udało mi się znaleźć taką stronę: https://developer.arm.com/documentation/ddi0439/b/Floating-Point-Unit/FPU-Functional-Description/FPU-instruction-set?lang=en Wynika mi z niej, że jedyna funkcja wspomagana sprzętowo przez FPU która nie jest zwykłą arytmetyką, to sqrtf. Zgadza się? Wszystkie inne, typu sin, cos, sqrt, pow, log etc. będą korzystać z softwareowej implementacji?

2. Skoro FPU obsługuje tylko float, to jak są wykonywane operacje na double? Typu mnożenie, odejmowanie itp.?

3. Czy jest jakiś sposób, żeby zapisać dane w pamięci flash (np. kilka obrazków) i potem ładować je w miarę potrzeby tak, żeby nie siedziały wszystkie w RAMie w trakcie wykonywania programu?

4. Po podłączeniu NUCLEO-L476RG do komputera, system rozpoznaje urządzenie jako dysk NODE_L476RG o pojemności 3 MB. Jest to zaskakujące, bo wszędzie jest napisane, że płytka ma tylko 1 MB. W dodatku wygląda to jak jakiś osobny dysk, a nie ten na którym znajduje się kod programu. Czy jest jakiś sposób by program wykorzystywał tę przestrzeń? Jeśli nie to po co ona jest?

Link to post
Share on other sites

Cześć,

Mam problem przez który funkcja lcd_copy() powoduje że nie dzieła mi program. Jest w momencie kursu gdzie ta funkcja jest pierwszy raz wywoływana.

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  lcd_init();

  for (int y = 0; y < LCD_HEIGHT; y++) {
    for (int x = 0; x < LCD_WIDTH; x++) {
      lcd_put_pixel(x, y, __REV16(x / 10 + y * 16));
    }
  }

  lcd_copy();
  while (1)
  {

Kiedy w tym miejscu NIE wywołuję funkcji lcd_copy(), wszystko jest w porządku. Kiedy ją wywołuje nie może się nawet chyba program załadować i debuger traci połączenie. Tak wygląda moja consola w CubeIDE

1.thumb.png.55f7d96369cd4bc0e1fe46d8e34cacae.png

Waiting for debugger connection...
Debugger connected
Debugger connection lost.
Shutting down...

Nie wiem czemu to się dzieje.
Tak wyglądają kody moich plików lcd.h


#pragma once

#include <stdint.h>

#define LCD_WIDTH	160
#define LCD_HEIGHT	128

//Definicje kolorów z odwróconą kolejnością bajtów
#define BLACK			0x0000
#define RED			0x00f8
#define GREEN			0xe007
#define BLUE			0x1f00
#define YELLOW			0xe0ff
#define MAGENTA			0x1ff8
#define CYAN			0xff07
#define WHITE			0xffff

void lcd_init(void); // Inicjalizacja wyświetlacza
void lcd_put_pixel(int x, int y, uint16_t color);
void lcd_copy(void); // Przesłanie zawartości bufora

Oraz pliku lcd.c


#include "lcd.h"
#include "spi.h"

#define ST7735S_SLPOUT			0x11
#define ST7735S_DISPOFF			0x28
#define ST7735S_DISPON			0x29
#define ST7735S_CASET			0x2a
#define ST7735S_RASET			0x2b
#define ST7735S_RAMWR			0x2c
#define ST7735S_MADCTL			0x36
#define ST7735S_COLMOD			0x3a
#define ST7735S_FRMCTR1			0xb1
#define ST7735S_FRMCTR2			0xb2
#define ST7735S_FRMCTR3			0xb3
#define ST7735S_INVCTR			0xb4
#define ST7735S_PWCTR1			0xc0
#define ST7735S_PWCTR2			0xc1
#define ST7735S_PWCTR3			0xc2
#define ST7735S_PWCTR4			0xc3
#define ST7735S_PWCTR5			0xc4
#define ST7735S_VMCTR1			0xc5
#define ST7735S_GAMCTRP1		0xe0
#define ST7735S_GAMCTRN1		0xe1

static void lcd_cmd(uint8_t cmd)
{
	HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_Transmit(&hspi2, &cmd, 1, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
}

static void lcd_data(uint8_t data)
{
	HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_Transmit(&hspi2, &data, 1, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
}

static void lcd_data16(uint16_t value){
	lcd_data(value >> 8);
	lcd_data(value);
}

#define CMD(x)			((x) | 0x100)

static void lcd_send(uint16_t value)
{
	if (value & 0x100) {
		lcd_cmd(value);
	} else {
		lcd_data(value);
	}
}

static const uint16_t init_table[] = {
  CMD(ST7735S_FRMCTR1), 0x01, 0x2c, 0x2d,
  CMD(ST7735S_FRMCTR2), 0x01, 0x2c, 0x2d,
  CMD(ST7735S_FRMCTR3), 0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d,
  CMD(ST7735S_INVCTR), 0x07,
  CMD(ST7735S_PWCTR1), 0xa2, 0x02, 0x84,
  CMD(ST7735S_PWCTR2), 0xc5,
  CMD(ST7735S_PWCTR3), 0x0a, 0x00,
  CMD(ST7735S_PWCTR4), 0x8a, 0x2a,
  CMD(ST7735S_PWCTR5), 0x8a, 0xee,
  CMD(ST7735S_VMCTR1), 0x0e,
  CMD(ST7735S_GAMCTRP1), 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22,
                         0x1f, 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10,
  CMD(ST7735S_GAMCTRN1), 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e,
                         0x30, 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10,
  CMD(0xf0), 0x01,
  CMD(0xf6), 0x00,
  CMD(ST7735S_COLMOD), 0x05,
  CMD(ST7735S_MADCTL), 0xa0,
};

void lcd_init(void)
{
  int i;

  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
  HAL_Delay(100);
  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
  HAL_Delay(100);

  for (i = 0; i < sizeof(init_table) / sizeof(uint16_t); i++) {
    lcd_send(init_table[i]);
  }

  HAL_Delay(200);

  lcd_cmd(ST7735S_SLPOUT);
  HAL_Delay(120);

  lcd_cmd(ST7735S_DISPON);
}


#define LCD_OFFSET_X  1
#define LCD_OFFSET_Y  2

static uint16_t frame_buffer[LCD_WIDTH * LCD_HEIGHT];

static void lcd_set_window(int x, int y, int width, int height){
	lcd_cmd(ST7735S_CASET);
	lcd_data16(LCD_OFFSET_X + x);
	lcd_data16(LCD_OFFSET_X + x + width - 1);

	lcd_cmd(ST7735S_RASET);
	lcd_data16(LCD_OFFSET_Y + y);
	lcd_data16(LCD_OFFSET_Y + y + height - 1);
}


void lcd_put_pixel(int x, int y, uint16_t color)
{
	frame_buffer[x + y * LCD_WIDTH] = color;
}

void lcd_copy(void)
{
	lcd_set_window(0, 0, LCD_WIDTH, LCD_HEIGHT);
	lcd_cmd(ST7735S_RAMWR);
	HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_Transmit(&hspi2, (uint8_t*)frame_buffer, sizeof(frame_buffer), HAL_MAX_DELAY);
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
}

Bardzo proszę o pomoc, bo to dla mnie mikrokontrolery to świeży temat i nie umiem sobie z tym problem dać sobie rady.

Link to post
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

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.