2026年2月17日 星期二

[OTTO GO] 動畫測試-利用LVGL技術,一次播4張

 

1.請參閱前一篇文章,轉換成4張圖檔。

2.並按照前一篇文章,把產生的4個.c檔案變成4個.h和4個.c的檔案,然後放到主檔案的目錄。

3.arduino程式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
  ESP32 + Adafruit_ST7789(240x320) 播放 tile000~tile003 的 RGB565 圖 (320x240)

  TFT pins:
    MOSI=19, SCLK=18, CS=5, DC=16, RST=23

  前提:
  - tile000.c ~ tile003.c 各自只保留像素陣列(uint8_t[]),不要包含 LVGL 的 lv_img_dsc_t
  - 若有 LV_ATTRIBUTE_* 巨集,需在 .c 最上方補上空巨集定義
*/

#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>

#include "tile000.h"
#include "tile001.h"
#include "tile002.h"
#include "tile003.h"

// ===== TFT pins =====
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS    5
#define TFT_DC   16
#define TFT_RST  23

Adafruit_ST7789 tft(TFT_CS, TFT_DC, TFT_RST);

// 固定尺寸
static const uint16_t W = 320;
static const uint16_t H = 240;
static const uint32_t FRAME_BYTES = (uint32_t)W * (uint32_t)H * 2u;

// 一行 buffer:320*2 = 640 bytes
static uint16_t lineBuf[W];

// 你的 .c 匯出多數是 little-endian RGB565(低位元組在前)
static const bool SOURCE_IS_LITTLE_ENDIAN = true;

static inline uint16_t read565(const uint8_t *p) {
  if (SOURCE_IS_LITTLE_ENDIAN) return (uint16_t)p[0] | ((uint16_t)p[1] << 8);
  else return ((uint16_t)p[0] << 8) | (uint16_t)p[1];
}

void drawRGB565_320x240(const uint8_t *dataBytes) {
  tft.startWrite();
  tft.setAddrWindow(0, 0, W, H);

  const uint32_t rowBytes = (uint32_t)W * 2u;

  for (uint16_t y = 0; y < H; y++) {
    const uint8_t *row = dataBytes + (uint32_t)y * rowBytes;

    for (uint16_t x = 0; x < W; x++) {
      lineBuf[x] = read565(row + (uint32_t)x * 2u);
    }

    // 一次推一行
    tft.writePixels(lineBuf, W, true);
  }

  tft.endWrite();
}

void setup() {
  Serial.begin(115200);
  delay(200);

  SPI.begin(TFT_SCLK, -1, TFT_MOSI, TFT_CS);

  tft.init(240, 320);
  tft.setRotation(1);          // 320x240
  tft.fillScreen(ST77XX_BLACK);

  Serial.printf("TFT size: %d x %d\n", tft.width(), tft.height());
  Serial.printf("Frame bytes expected: %u\n", (unsigned)FRAME_BYTES);

  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.setCursor(8, 8);
  tft.print("tile player");
}

void loop() {
  // 依序播放 4 幀
  drawRGB565_320x240(tile000_map);
  delay(60);

  drawRGB565_320x240(tile001_map);
  delay(60);

  drawRGB565_320x240(tile002_map);
  delay(60);

  drawRGB565_320x240(tile003_map);
  delay(60);
}

沒有留言:

張貼留言