跳轉到主要內容

低硬體成本上的TouchGFX

本節討論如何在RAM和快閃記憶體大小有限、無加速且與外部快閃記憶體和顯示器的連線速度慢的低成本硬體上使用TouchGFX。

我們將提供一些關於為指定硬體編寫最佳應用程式的建議。

本節將以STM32G071 nucleo板和X-Nucleo-GFX01M1擴展板為例,描述如何對硬體使用應用範例。

Nucleo-G071RB和X-Nucleo-GFX01M1擴展板

硬體概述

該套件中的硬體設定包括STM32G071 MCU、SPI NOR flash、SPI顯示器和搖杆按鈕。

元件 
MCUSTM32G071RB
MCU RAM32 Kb
MCU Flash128 Kb
顯示器Displaytech DT022CTFT
顯示器解析度240 x 320
顯示器控制器ILI9341V
顯示器連接SPI
顯示器連線速度32 MHz
NOR FlashMacronix MX25L6433F
NOR Flash大小64 Mbit
NOR Flash連線速度32 MHz

顯示器連接到SPI1外設,而快閃記憶體連接到SPI2外設。 因此,MCU能夠在向顯示器發送資料的同時從快閃記憶體讀取資料。

具有X-Nucleo-GFX01M1架構的Nucleo-G071RB

GPIO配置

信號GPIO引腳
顯示CSPB5
顯示DCXPB3
顯示SCKPA5
顯示MOSIPA7
顯示TEPA0
Flash CSPB9
Flash SCKPB13
Flash MOSIPC3
Flash MISOPC2

上表列出了快閃記憶體和顯示器信號的GPIO分配。 這些信號可通過示波器或邏輯分析儀進行監測。 這在諸如性能等問題的Debug中非常實用。

啟動專案

在TouchGFX Designer中,可以輕鬆地為STM32G071RB Nucleo評估套件啟動一個專案。 點擊"Create New",然後選擇STM32G071 Nucleo。 此範本專為Nucleo-G071RB套件和X-Nucleo-GFX01M1顯示板而開發。

Nucleo-G071RB的新專案

該範本支援NOR flash、顯示器和按鈕。 顯示器有豎屏和橫屏兩種使用模式。

可以在TouchGFX Designer中的Config -> Display部分修改顯示器方向:

選擇豎屏或橫屏顯示

X-Nucleo-GFX01M1 Shield上的顯示器原本是豎屏(高度大於寬度),但很容易改為橫屏。

顯示器更新

如上文所述,顯示器解析度為240 x 320像素。 總共76,800像素或153,600位元組。 MCU與顯示器之間的SPI連接的運行頻率為32 MHz。 因此,傳送速率可以達到4 MB/s或2M像素/s。

顯示器的刷新頻率為76.1 Hz,因此每幀為13.14 ms。

顯示器的撕裂效應信號

這意味著有最多13 ms的時間來發送下一幀的資料。 在這段時間裡,我們可以發送2,000,000像素/s / 76 fps = 26,280像素/幀或全螢幕的34%。
事實上,由於協議的原因,我們不能在SPI匯流排上維持該傳送速率,因此不能指望發送量超過全幀的約30%。

如果應用更新的像素數超過此值,硬體將無法在每幀的時間以內完成發送。 結果是顯示器將在全部更新結束前開始顯示更新的幀。 因此,用戶有時會看到原來的幀與新的幀混合在一起。

對於一些動畫而言,用戶注意不到這一點,但在其他情況下可能無法接受。

因此,我們建議將更新率維持在30%以下。 如 通過漸進式地分步更新幀。

因此,一般來說最好在螢幕上擴展物件,而不是移動物件。

顯示器的撕裂效應信號

當星形移動到右側時,必須更新星形覆蓋的所有像素。 如果只擴展星形,則只需更新新像素。 在上一幀更新的像素保持不變。

繪製速度

向顯示器發送資料的頻率為最高32 MHz。

串列快閃記憶體能以與顯示器發送相同的速度運行。 這意味著串列快閃記憶體的速度足夠快,能以最高速度向顯示器供應資料。

這只有在快閃記憶體中的影像位元格式為RGB565時才能實現。 在這種情況下,從快閃記憶體讀取的2個位元組等於1個像素,在顯示器上也是2個位元組。
如果快閃記憶體中的像素格式是ARGB8888,則需要從快閃記憶體中讀取兩倍的資料量才能在顯示器上生成1個像素,並且串列快閃記憶體將無法跟上顯示器的速度。

當發生這種情況時,不再繼續向顯示器發送資料,並且將不可能更新顯示器上一個幀資料的30%。 有一種可能的辦法是將影像移動到內部快閃記憶體,另一種辦法是更改像素格式。

其他的工具不受快閃記憶體速度的限制。 如 方框小工具,用於繪製彩色矩形。 此工具速度很快,比顯示器資料發送速度要快許多。 其他小工具(如直線和圓)需要使用更多CPU資源。 這些小工具無法以發送到顯示器的速度來生成像素。 對於使用這些小工具的應用,不能期望能夠更新顯示器上每幀的30%。

點擊這裡瞭解像素渲染的複雜性

使用串列快閃記憶體時TouchGFX的限制

應用程式撰寫者必須認識到,在具有串列快閃記憶體的STM32G0上使用TouchGFX時的幾點限制。

紋理映射器

紋理映射器小工具(TextureMapper、AnimationTextureMapper和 ScalableImage)不能繪製存儲在外部SPI快閃記憶體中的圖像。 原因在於,用存儲在串列快閃記憶體中的影像無法獲得可接受的性能,如圖像旋轉。

為了通過紋理映射器使用圖像,必須將圖像保存在內部快閃記憶體或RAM中。 通過在TouchGFX Designer中修改圖像配置,可以輕鬆地將圖像保存在內部快閃記憶體中。

轉至“Images ”選項卡並選中圖像。 在視窗的右側,將“Section”屬性更改為“IntFlashSection”。

將圖像放入內部快閃記憶體

紋理映射器的程式碼量過大,不能包含在所有專案中。 因此,對於STM32G0專案,默認禁用紋理映射器。 這意味著您必須先啟用紋理映射器,然後才能在STM32G0專案中使用它。

轉至“Config”選項卡,選擇“Framework Features”,並點擊相關的紋理映射器或一組紋理映射器。

為特定圖像格式啟用紋理映射器

還可以使用點陣圖緩存將圖像暫時移動到RAM

點陣圖繪製器

可通過圖像為直線、圓和DynamicGraph上色。 這不適用於存儲在SPI快閃記憶體中的圖像。 使用這些小工具的圖像必須放在內部快閃記憶體或RAM中。

L8調色板

L8格式的圖像可以用在具有串列快閃記憶體的硬體上。 限制條件是調色板資料必須放在內部快閃記憶體中(也是出於性能考量)。

通過在TouchGFX Designer中將“Extra Section”修改為“IntFlashSection”,可以將調色板移動到內部快閃記憶體。

驅動程式

應用範本是使用TouchGFX Generator創建的。 點擊此處閱讀TouchGFX Generator的更多相關內容。 TouchGFX Generator生成HAL層,它連接TouchGFX框架與一組底層驅動器(已在該應用範本中實現)。 該應用範本的底層驅動位於專案的Core/Src資料夾中。

驅動器位於3個檔中:

驅動器檔案
顯示器Core/Src/MB1642BDisplayDriver.c
FlashCore/Src/MB1642BDataReader.c
按鈕Core/Src/MB1642BButtonController.cpp

顯示器

顯示器使用標準SPI協定。 為了配置顯示器,可以對顯示器中的許多寄存器執行寫入。 在資料發送到顯示器時鎖定選擇的晶片。 使用額外的GPIO(DCX)將指令位元組與資料位元組區分開來。

驅動程式使用DMA通道發送顯示器像素資料。 這樣就可以在MCU計算像素的同時進行發送。 DMA完成中斷被用來釋放已發送資料的存儲空間以便在將來繪製時重複使用,以及在有新資料可用時重新開始發送資料。

由於CS和CDX引腳必須在小配置封裝之間切換並位於其內部,因此不通過DMA發送配置資料。

在發送配置資料時,驅動程式使用8位元模式的SPI,但在發送像素資料時改為16位元模式。 其中的原因在於,MCU記憶體以小端模式讀取。 RGB565格式的像素存儲在RAM中,首先是低位元組(G和B),然後是高位元組(R和G)。 當8位SPI為進行發送而讀取記憶體時,維持此順序不變。 當SPI為16位元模式時,按16位元RGB565從記憶體讀取資料,並按顯示器的正確順序發送資料。

對於不使用16位DMA的驅動,必須在發送前交換像素中的位元組。

初始化

顯示器初始化是在函數MB1642BDisplayDriver_DisplayInit(void)中完成的

驅動程式按照建議的上電順序向顯示器發送6個指令:

  1. 退出睡眠模式(11h)
  2. 進入正常模式(13h)
  3. 利用MX和BGR位置設定記憶體存取控制(36h)
  4. 設置像素格式(3Ah)為16位格式
  5. 撕裂效應線開啟(35h)
  6. 設置撕裂掃描線(44h)使其 = 0

驅動會在這些指令之間休眠100 ms。

撕裂效應

來自顯示器的撕裂效應(TE)信號非常重要。 它使應用程式能夠正確地與顯示器同步。 這有助於應用程式避免顯示器上的撕裂效應。 顯示器在開始更新週期時生成信號。 MCU使用此信號向顯示器發送資料。

TE信號連接到MCU的外部中斷輸入。 CubeMx生成並配置該引腳上的中斷。

驅動中的callback 指示TouchGFX開始繪製:

MB1642BDisplayDriver.c
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
...
touchgfxSignalVSync();
}

外部快閃記憶體

顯示板卡上的SPI NOR flash是標準SPI flash。 該驅動比顯示器驅動簡單。 無需專門初始化即可從快閃記憶體讀取資料。

該驅動可使用輪詢SPI(忙碌等待每個位元組)或DMA讀取資料。 開始DMA接收的時間接近於以輪詢模式讀取20個位元組所需的時間,因此短讀通常較慢。 另一方面,DMA在中斷期間繼續運行,並且可以在MCU忙於渲染像素時在後臺運行。 出於這個原因使用兩種方法。

快閃記憶體驅動使用與顯示器驅動不同的DMA通道,因此資料接收和像素發送可以同時運行。

連結器腳本

連結器控制應用中各種資料所在的位置。 這是在連結器腳本中指定的。 下面是gcc編譯器的連結器腳本的第一部分:

MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 36K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
SPI_FLASH (r) : ORIGIN = 0x90000000, LENGTH = 8M
}

它宣告NOR flash從位址0x90000000開始。 該值是任意選擇的,但快閃記憶體載入器要求提供。

第二部分將圖像(ExtFlashSection)和字體(FontFlashSection)資料放在SPI快閃記憶體中。

  ExtFlashSection :
{
*(ExtFlashSection ExtFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >SPI_FLASH

FontFlashSection :
{
*(FontFlashSection FontFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >SPI_FLASH

通過向連結器腳本中添加相似分區,可將其他資料放入SPI快閃記憶體。

快閃記憶體下載

G071 TouchGFX開發板設置包含STM32CubeProgrammer的快閃記憶體載入器。 此快閃記憶體載入器可將資料寫入SPI NOR flash。

快閃記憶體載入器位於文件gcc/S25FL032P_STM32G071B-NUCLEO.stldr

STM32CubeIde專案可從IDE直接燒錄,但IAR或Keil則必須從STM32CubeProgrammer進行燒錄。

STM32CubeProgrammer中最初不能使用快閃記憶體載入器,必須將stldr複製到安裝資料夾進行安裝:

將快閃記憶體載入器複製到STM32CubeProgrammer安裝資料夾

現在,可以正常地在STM32CubeProgrammer中選擇快閃記憶體載入器:

將快閃記憶體載入器複製到STM32CubeProgrammer安裝資料夾

Tip
快閃記憶體載入器在Nucleo-G071RB開發板上僅能使用特定的GPIO配置 。

如果在自訂硬體上對串列快閃記憶體使用其他GPIO配置,則必須相應地修改快閃記憶體載入器。

按鈕

按鈕驅動十分簡單。 它對MB1642B上的搖杆和Nucleo板上的藍色按鈕使用的5個GPIO的狀態進行採樣。

此按鈕驅動作為BottonController安裝在TouchGFX中。 這意味著可以直接在TouchGFX Designer中點擊按鈕以便使用。 還可以在用戶程式碼中使用它們,例如:

void Screen1View::handleKeyEvent(uint8_t key)
{
if (key == '6')
{
application().gotoScreen2Screen();
}
}

使用的鍵碼:

程式碼
'4'
'6'
'8'
'2'
'5'
藍色按鈕'0'

這些鍵可以通過模擬器的小鍵盤來使用。