• 正文
    • 1、前言
    • 2、字符顯示
    • 3、優(yōu)化方式
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

一段小修改,讓我的LCD顯示字符速率翻倍

02/26 11:20
1201
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

1、前言

之前曾經(jīng)介紹過(guò)在TFTLCD顯示屏中使用DMA傳輸可以大幅度的提升傳輸效率。

但是當(dāng)時(shí)只修改了原先全屏刷新的算法以及圖片刷新的LCD算法。

今天測(cè)試在顯示字符的時(shí)候,依舊效率低下。

于是自己查看了一下字符顯示的算法,嘗試能不能提高一下效率。

2、字符顯示

void ST7789_WriteChar(uint16_t x, uint16_t y, char ch, FontDef font, uint16_t color, uint16_t bgcolor){? uint32_t i, b, j;? ST7789_Select();? ST7789_SetAddressWindow(x, y, x + font.width -?1, y + font.height -?1);??for?(i =?0; i < font.height; i++) {? ? b = font.data[(ch -?32) * font.height + i];? ??for?(j =?0; j < font.width; j++) {? ? ??if?((b << j) &?0x8000) {? ? ? ? uint8_t?data[] = {color >>?8, color &?0xFF};? ? ? ? ST7789_WriteData(data, sizeof(data));? ? ? }? ? ??else?{? ? ? ? uint8_t?data[] = {bgcolor >>?8, bgcolor &?0xFF};? ? ? ? ST7789_WriteData(data, sizeof(data));? ? ? }? ? }? }? ST7789_UnSelect();}

ST7789_WriteData這條命令是利用DMA傳輸?shù)模虼擞绊懶实闹饕蚴秋@示字符算法的效率。

函數(shù)參數(shù)傳遞進(jìn)來(lái)的是一個(gè)字符、坐標(biāo)、字體定義、前景色和背景色,我們逐行來(lái)分析這個(gè)函數(shù)。

ST7789_Select();ST7789_SetAddressWindow(x, y, x +?font.width?-?1, y +?font.height?-?1);

該部分用于SPI通訊選中,并且設(shè)置顯示窗口的地址。

? for (i = 0; i < font.height; i++) {? ? for (j = 0; j < font.width; j++) {? ? ? }? ? }? }

兩個(gè)for循環(huán)代表著這個(gè)函數(shù)采用的逐行逐列刷新像素的方式將字符描出來(lái)。

if?((b << j) &?0x8000) {? ?uint8_t?data[] = {color >>?8, color &?0xFF};? ?ST7789_WriteData(data, sizeof(data));}else?{? ?uint8_t?data[] = {bgcolor >>?8, bgcolor &?0xFF};? ?ST7789_WriteData(data, sizeof(data));}

這段在顯示每個(gè)像素點(diǎn)數(shù)據(jù)的時(shí)候,利用將字模數(shù)據(jù)的每一行(存放在變量b)判斷每個(gè)像素點(diǎn)的掩膜值來(lái)確定這個(gè)像素是顯示前景色還是背景色。

當(dāng)然這里最大的一個(gè)問(wèn)題還是,該方法是每個(gè)像素逐點(diǎn)刷新的,會(huì)頻繁的調(diào)用ST7789_WriteData這個(gè)命令。

3、優(yōu)化方式

我們注意到,SPI的傳輸是可以多個(gè)數(shù)據(jù)包一起發(fā)送的,因此我們嘗試修改一下刷新方式,可以創(chuàng)建一個(gè)緩存區(qū)存放一個(gè)字符區(qū)域的整體內(nèi)容(前景色背景色處理完之后的數(shù)據(jù)),之后利用硬件SPI統(tǒng)一發(fā)送,而不是像原先那樣子對(duì)每個(gè)字符。

void?ST7789_WriteChar(uint16_t x, uint16_t y,?char?ch, FontDef font, uint16_t color, uint16_t bgcolor){? ? uint32_t i, j;? ? uint16_t *pixel_buffer; ?// 緩沖區(qū),用于存儲(chǔ)像素?cái)?shù)據(jù)? ??uint16_t?width?=?font.width;? ??uint16_t?height?=?font.height;? ??// 計(jì)算像素?cái)?shù)據(jù)緩沖區(qū)的大?。好肯袼?2 字節(jié)(16 位顏色),寬 × 高? ??uint16_t?buffer_size?=?width * height;? ? uint8_t buffer[2?* buffer_size]; ?// 2 × 16-bit = 32-bit per pixel? ??// 填充緩沖區(qū)? ??for?(i =?0; i < height; i++)?? ? {? ? ? ??uint16_t?row_data?=?font.data[(ch -?32) * height + i];? ? ? ??for?(j =?0; j < width; j++)?? ? ? ? {? ? ? ? ? ??uint32_t?index?=?(i * width + j) *?2;? ? ? ? ? ??if?((row_data << j) &?0x8000)?? ? ? ? ? ? {? ? ? ? ? ? ? ? buffer[index] = color >>?8;? ? ? ? ? ? ? ? buffer[index +?1] = color &?0xFF;? ? ? ? ? ? }?? ? ? ? ? ??else?? ? ? ? ? ? {? ? ? ? ? ? ? ? buffer[index] = bgcolor >>?8;? ? ? ? ? ? ? ? buffer[index +?1] = bgcolor &?0xFF;? ? ? ? ? ? }? ? ? ? }? ? }
? ??// 寫(xiě)入數(shù)據(jù)? ? ST7789_Select();? ? ST7789_SetAddressWindow(x, y, x + width -?1, y + height -?1);? ? ST7789_WriteData(buffer, sizeof(buffer));? ? ST7789_UnSelect();}

這種辦法雖然會(huì)犧牲臨時(shí)變量,需要更多的空間,但是實(shí)際上使用中極大的提升了刷新速度。

相關(guān)推薦