0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【GD32H757Z海棠派開發(fā)板使用手冊】第十四講 TFT-8080口液晶顯示

聚沃科技 ? 2024-09-19 09:21 ? 次閱讀

14.1實驗內(nèi)容

通過本實驗主要學(xué)習(xí)以下內(nèi)容:

  • LCD顯示原理
  • EXMC NOR/SRAM模式時序和8080并口時序
  • LCD顯示控制

14.2實驗原理

使用MCU的EXMC外設(shè)實現(xiàn)8080并口時序,和TFT-LCD控制器進(jìn)行通信,控制LCD顯示圖片、字符、色塊等。

14.2.1TFT-LCD介紹

薄膜晶體管液晶顯示器(英語:Thin film transistor liquid crystal display,常簡稱為TFT-LCD)是多數(shù)液晶顯示器的一種,它使用薄膜晶體管技術(shù)改善影象品質(zhì)。雖然TFT-LCD被統(tǒng)稱為LCD,不過它是種主動式矩陣LCD,被應(yīng)用在電視、平面顯示器及投影機上。

簡單說,TFT-LCD面板可視為兩片玻璃基板中間夾著一層液晶,上層的玻璃基板是彩色濾光片、而下層的玻璃則有晶體管鑲嵌于上。當(dāng)電流通過晶體管產(chǎn)生電場變化,造成液晶分子偏轉(zhuǎn),藉以改變光線的偏極性,再利用偏光片決定像素的明暗狀態(tài)。此外,上層玻璃因與彩色濾光片貼合,形成每個像素各包含紅藍(lán)綠三顏色,這些發(fā)出紅藍(lán)綠色彩的像素便構(gòu)成了面板上的視頻畫面。

為了對TFT-LCD的顯示進(jìn)行控制,需要通過接口和液晶屏通信,但所謂與液晶屏通信,實際上還是與液晶屏驅(qū)動控制芯片在通信,而主控制器需要按控制芯片支持的通信進(jìn)行交互,通常有UART、IIC、SPI、8080、MIPI等各類接口。另外需要注意的一點是:一般支持普通MCU接口的LCD驅(qū)動芯片,都需要內(nèi)置GRAM(Graphics RAM),至少能存儲一個屏幕的數(shù)據(jù)。

這這里,我們使用了8080接口通過并行總線傳輸控制命令和數(shù)據(jù),并通過往LCD液晶模組自帶的GRAM更新數(shù)據(jù)實現(xiàn)屏幕的刷新。

GD32H757海棠派開發(fā)板TFT-LCD如下圖所示,采用了ILI9488 LCD驅(qū)動器,分辨率320*480,支持多種通信接口,在GD32H757上,適合使用16-bit Parallel MCU Interface接口進(jìn)行通信,開發(fā)板配套的LCD模塊也采用了該接口設(shè)計和開發(fā)板進(jìn)行連接。

wKgZomZ7bSqAZt66AAR42Jm9V_o961.png

14.2.2LCD 8080并口時序介紹(16-bit Parallel MCU Interface)

8080接口是由英特爾設(shè)計,是一種并行、異步、半雙工通信協(xié)議,作用是用于外擴RAM、ROM,后面也用于LCD接口。并行接口又分為8位/16位/24位 三種,顧名思義,就是數(shù)據(jù)總線的位寬。

  • 如下圖所示是16-bit Parallel MCU Interface的接口和MCU的連接信號
wKgZomZ7bTaANeiMAACBuF9C9ek658.png
  • 如下圖所示是LCD驅(qū)動器16BIT 8080并口讀寫時序:
  • CS拉低后,并口DATA IO在WR的上升沿被采樣;
  • 可以理解為16線的SPI,而WR是寫“CLK”,RD是讀“CLK”;
  • 但這里還多了D/C引腳用于選擇傳輸命令或數(shù)據(jù)
wKgaomZ7bU6AB535AAIC0zOeKaw118.pngwKgZomZ7bVSAAKVDAAHJ9-R-G2w527.png

  • 8080接口的RGB顏色數(shù)據(jù)編碼
  • 像素信息用RGB三原色表示,所以向液晶屏傳輸?shù)臄?shù)據(jù)幀主要也就是傳輸?shù)腞GB顏色數(shù)據(jù)。
  • 像素的顏色數(shù)據(jù)并不總是用 8R8G8B的24位真彩色 表示,共有下面幾種表示情況:
  • 12-bits/pixel (R 4-bit, G 4-bit, B 4-bit), 4,096 Colors, 簡稱444;
  • 16-bits/pixel (R 5-bit, G 6-bit, B 5-bit), 65,536 Colors, 簡稱565;
  • 18-bits/pixel (R 6-bit, G 6-bit, B 6-bit), 262,144 Colors, 簡稱666;
  • 24-bits/pixel (R 8-bit, G 8-bit, B 8-bit), 16,777,216 Colors, 簡稱888;
    不同顏色表示方法和不同的總線位寬相組合,就會組合成多種RGB顏色數(shù)據(jù)編碼。
  • 綜合顯示效果、內(nèi)存資源開銷等,我們采取了RGB565像素格式,這樣16BIT 8080每次傳輸就是一個像素點的像素值,傳輸數(shù)據(jù)就為像素顏色值。

14.2.3EXMC外設(shè)和EXMC NOR/SRAM模式實現(xiàn)8080時序

  • 這里我們使用EXMC中時序和接口類似的NOR/SRAM模式,來實現(xiàn)8080接口驅(qū)動TFT-LCD顯示。
  • 這里我們使用SRAM模式異步模式A(擴展模式),時序如下圖:
wKgZomZ7bWaAbtWzAACeFGwmKV0242.png

我們對比上面的時序和16-bit Data Bus 8080 LCD時序,發(fā)現(xiàn)一些信號的時序是類似的,我們可以將這些信號進(jìn)行對應(yīng):

EXMC_NEx -> CSx

EXMC_NOE->RDx

EXMC_NWE->WR

EXMC_D[15:0]->DB[15:0]

EXMC_Ax->D/C

這里巧妙的是使用EXMC_Ax引腳實現(xiàn)D/C的數(shù)據(jù)/命令切換功能,所以我們只需要選擇一個方便布線的EXMC_Ax引腳,然后在軟件中對該引腳對應(yīng)的EXMC邏輯地址進(jìn)行操作就可以實現(xiàn)程序讀寫不同地址時,D/C引腳的狀態(tài)切換,從而實現(xiàn)訪問一個EXMC地址時是數(shù)據(jù)或命令類似,訪問該地址位反向的任意地址就是另外一個類型。對于程序中邏輯地址的影響,除了Ax引腳的選擇外還有NEx引腳的選擇。NE[0]-NE[3]對應(yīng)如下圖的NOR/SRAM BANK下的Region0-Region3。

wKgaomZ7bXGAS9FaAADKryj292U804.png

14.3硬件設(shè)計

在紅楓派開發(fā)板設(shè)計中,我們使用EXMC_NE1引腳作為CS,EXMC_A12引腳作為D/C,同時LCD觸摸接口使用SPI,LCD_BL為背光控制引腳,這里的引腳選用了帶PWM的引腳,可以實現(xiàn)LCD的背光亮度調(diào)節(jié)。

wKgaombrfAuADy4qAAL5lZT3t2g080.png

14.4代碼解析

14.4.1CSx、D/C、BL相關(guān)功能定義和注冊;

在EXMC LCD驅(qū)動代碼中存在和電路設(shè)計匹配的變更點,往往讓開發(fā)者頭大,需要詳細(xì)閱讀用戶手冊來進(jìn)行配置調(diào)整、讀寫地址調(diào)整;而在我們的驅(qū)動文件bsp_8080_lcd.c中定義注冊背光引腳、Ax、NEx引腳,當(dāng)硬件設(shè)計變更時只需要在這里調(diào)整,驅(qū)動就可以在新的硬件中正常使用。

C
//用戶配置定義區(qū)
#define BACK_LIGHT_DUTY 80

TIMER_CH_DEF(LCD_8080_BL,TIMER3,1,TIMER_CH_PWM_HIGH,D,13,AF_PP,GPIO_AF_2);

#define EXMC_Ax 12
AFIO_DEF(EXMC_Ax_GPIO,G,2,AF_PP,GPIO_AF_12);

#define EXMC_NEx 1
AFIO_DEF(EXMC_NEx_GPIO,G,9,AF_PP,GPIO_AF_12);

GPIO_DEF(LCD_8080_RST,D,12,OUT_PP,RESET,NULL);
//驅(qū)動內(nèi)部定義區(qū)
#define EXMC_LCD_D REG16(((uint32_t)(EXMC_BANK0_NORSRAM_REGIONx_ADDR(EXMC_NEx)))|BIT(EXMC_Ax)*2)
#define EXMC_LCD_C REG16(((uint32_t)(EXMC_BANK0_NORSRAM_REGIONx_ADDR(EXMC_NEx))))

14.4.2gpio和exmc初始化:

exmc使用了擴展模式,這樣讀和寫的時序可以單獨配置,因為LCD對讀和寫的要求時間是不同的,讀的時候速率不能太高,如果使用一種參數(shù)類型就會為了滿足讀的要求而降低寫的速率,影響最終刷屏的性能。這里主要調(diào)整讀和寫時的地址建立、數(shù)據(jù)建立時間,通常和硬件設(shè)計也有較大關(guān)系。

C
static void driver_exmc_lcd_16bit_gpio_init(void)
{
/* EXMC clock enable */
rcu_periph_clock_enable(RCU_EXMC);

/* EXMC enable */
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_GPIOF);
rcu_periph_clock_enable(RCU_GPIOG);

/* configure GPIO D[0-15] */
gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);

gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);

/* configure NOE NWE */
gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_4 | GPIO_PIN_5);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_4 | GPIO_PIN_5);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_4 | GPIO_PIN_5);
}

void driver_exmc_lcd_init(uint32_t norsram_region)
{

#define LCD_READ_DATA_SETTIME_NS 50
#define LCD_READ_ADDR_SETTIME_NS 10

#define LCD_WRITE_DATA_SETTIME_NS 20
#define LCD_WRITE_ADDR_SETTIME_NS 10

uint32_t ahb_clk=0;
exmc_norsram_parameter_struct nor_init_struct;
exmc_norsram_timing_parameter_struct nor_timing_read_init_struct;
exmc_norsram_timing_parameter_struct nor_timing_write_init_struct;

mpu_region_init_struct mpu_init_struct;
mpu_region_struct_para_init(&mpu_init_struct);

mpu_config(EXMC_BANK0_NORSRAM_REGIONx_ADDR(norsram_region),MPU_REGION_SIZE_64MB,MPU_AP_FULL_ACCESS,MPU_ACCESS_BUFFERABLE,MPU_ACCESS_NON_CACHEABLE,MPU_ACCESS_NON_SHAREABLE,MPU_INSTRUCTION_EXEC_NOT_PERMIT,MPU_TEX_TYPE0);

/* EXMC clock enable */
rcu_periph_clock_enable(RCU_EXMC);

driver_exmc_lcd_16bit_gpio_init();

nor_init_struct.read_write_timing = &nor_timing_read_init_struct;
nor_init_struct.write_timing = &nor_timing_write_init_struct;
exmc_norsram_struct_para_init(&nor_init_struct);
nor_init_struct.read_write_timing = &nor_timing_read_init_struct;
nor_init_struct.write_timing = &nor_timing_write_init_struct;

SystemCoreClockUpdate();
ahb_clk=rcu_clock_freq_get(CK_AHB);
/* config timing parameter */
nor_timing_read_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A;
nor_timing_read_init_struct.syn_data_latency = EXMC_DATALAT_2_CLK;
nor_timing_read_init_struct.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;
nor_timing_read_init_struct.bus_latency = 1;
nor_timing_read_init_struct.asyn_data_setuptime = LCD_READ_DATA_SETTIME_NS/(float)(1000000000.0f/ahb_clk);
nor_timing_read_init_struct.asyn_address_holdtime = 1;
nor_timing_read_init_struct.asyn_address_setuptime = LCD_READ_ADDR_SETTIME_NS/(float)(1000000000.0f/ahb_clk);

/* config timing parameter */
nor_timing_write_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A;
nor_timing_write_init_struct.syn_data_latency = EXMC_DATALAT_2_CLK;
nor_timing_write_init_struct.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;
nor_timing_write_init_struct.bus_latency = 1;
nor_timing_write_init_struct.asyn_data_setuptime = LCD_WRITE_DATA_SETTIME_NS/(float)(1000000000.0f/ahb_clk);
nor_timing_write_init_struct.asyn_address_holdtime = 1;
nor_timing_write_init_struct.asyn_address_setuptime =LCD_WRITE_ADDR_SETTIME_NS/(float)(1000000000.0f/ahb_clk);

/* config EXMC bus parameters */
nor_init_struct.norsram_region = norsram_region;
nor_init_struct.write_mode = EXMC_ASYN_WRITE;
nor_init_struct.extended_mode = ENABLE;
nor_init_struct.asyn_wait = DISABLE;
nor_init_struct.nwait_signal = DISABLE;
nor_init_struct.memory_write = ENABLE;
nor_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
// nor_init_struct.wrap_burst_mode = DISABLE;
nor_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
nor_init_struct.burst_mode = DISABLE;
nor_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
nor_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;
nor_init_struct.address_data_mux = DISABLE;

exmc_norsram_init(&nor_init_struct);

/* enable the EXMC bank0 NORSRAM */
exmc_norsram_enable(norsram_region);
}

14.4.3LCD數(shù)據(jù)、命令讀寫:

LCD的命令、數(shù)據(jù)的讀寫都通過EXMC來實現(xiàn),在讀寫EXMC的邏輯地址時對應(yīng)的波形會發(fā)送到LCD上,命令/數(shù)據(jù)目前通過地址引腳控制,所以我們需要定義兩個地址分別對應(yīng)命令、數(shù)據(jù)地址,對這兩個地址讀和寫就可以實現(xiàn)LCD讀寫數(shù)據(jù)、寫命令功能。

C
/**
* 說明 LCD寫數(shù)據(jù)
* 輸入 data: 要寫入的數(shù)據(jù)
* 返回值 無
*/
void bsp_8080_lcd_wr_data(__IO uint16_t data)
{
// delay_sysclk(1);
EXMC_LCD_D = data;
}

/**
* 說明 LCD寫寄存器編號/地址函數(shù)
* 輸入 regno: 寄存器編號/地址
* 返回值 無
*/
void bsp_8080_lcd_wr_regno(__IO uint16_t regno)
{
// delay_sysclk(1);
EXMC_LCD_C = regno; /* 寫入要寫的寄存器序號 */
}

/**
* 說明 LCD寫寄存器
* 輸入 regno:寄存器編號/地址
* 輸入 data:要寫入的數(shù)據(jù)
* 返回值 無
*/
void bsp_8080_lcd_write_reg(__IO uint16_t regno,__IO uint16_t data)
{
// delay_sysclk(1);
EXMC_LCD_C = regno; /* 寫入要寫的寄存器序號 */
// delay_sysclk(1);
EXMC_LCD_D = data; /* 寫入數(shù)據(jù) */
}

/**
* 說明 LCD讀數(shù)據(jù)
* 輸入 無
* 返回值 讀取到的數(shù)據(jù)
*/
static uint16_t bsp_8080_lcd_read_data(void)
{
// delay_sysclk(1);
return EXMC_LCD_D;
}

14.4.4LCD初始化

LCD初始化序列通常LCD驅(qū)動器廠家會提供相關(guān)寄存器配置,為了兼容不同的LCD,可以讀取LCD ID后執(zhí)行不同的驅(qū)動芯片初始化:

C
/**
* 說明 初始化LCD
* @note 該初始化函數(shù)可以初始化各種型號的LCD(詳見本.c文件最前面的描述)
*
* 輸入 無
* 返回值 無
*/
uint32_t bsp_8080_lcd_init(void)
{

bsp_8080_lcd_port_init();

driver_gpio_general_init(&LCD_8080_RST);

driver_gpio_pin_reset(&LCD_8080_RST);
delay_ms(10);
driver_gpio_pin_set(&LCD_8080_RST);

delay_ms(10);
bsp_8080_lcd_backlight_duty_set(BACK_LIGHT_DUTY);

bsp_8080_lcd_backlight_on(); /* 點亮背光 */

/* LCD的畫筆顏色和背景色 */
bsp_8080_lcd_parameter.g_point_color = WHITE; /* 畫筆顏色 */
bsp_8080_lcd_parameter.g_back_color = BLACK; /* 背景色 */

delay_ms(1); /* 初始化FSMC后,必須等待一定時間才能開始初始化 */

/* 嘗試9341 ID的讀取 */
bsp_8080_lcd_wr_regno(0XD3);
bsp_8080_lcd_parameter.id = bsp_8080_lcd_read_data(); /* dummy read */
bsp_8080_lcd_parameter.id = bsp_8080_lcd_read_data(); /* 讀到0X00 */
bsp_8080_lcd_parameter.id = bsp_8080_lcd_read_data(); /* 讀取0X93 */
bsp_8080_lcd_parameter.id <<= 8;
bsp_8080_lcd_parameter.id |= bsp_8080_lcd_read_data(); /* 讀取0X41 */


if (bsp_8080_lcd_parameter.id == 0X9488)
{
lcd_ex_ili9488_reginit(); /* 執(zhí)行ILI9388初始化 */
}
else if (bsp_8080_lcd_parameter.id == 0X9341)
{
lcd_ex_ili9341_reginit(); /* 執(zhí)行ILI9341初始化 */
}else{
bsp_8080_lcd_parameter.id = 0X9488;
bsp_8080_lcd_display_dir(0); /* 默認(rèn)為豎屏 */
bsp_8080_lcd_scan_dir(DFT_SCAN_DIR); /* 默認(rèn)掃描方向 */
return DRV_ERROR;
}

bsp_8080_lcd_display_dir(0); /* 默認(rèn)為豎屏 */
bsp_8080_lcd_scan_dir(DFT_SCAN_DIR); /* 默認(rèn)掃描方向 */
bsp_8080_lcd_clear(WHITE);

return DRV_SUCCESS;
}

/**
* @brief ILI9488寄存器初始化代碼
* @param 無
* @retval 無
*/
void lcd_ex_ili9488_reginit(void)
{
//************* Start Initial Sequence **********//
bsp_lcd_wr_regno(0XF7);
bsp_lcd_wr_data(0xA9);
bsp_lcd_wr_data(0x51);
bsp_lcd_wr_data(0x2C);
bsp_lcd_wr_data(0x82);

bsp_lcd_wr_regno(0XEC);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x02);
bsp_lcd_wr_data(0x03);
bsp_lcd_wr_data(0x7A);

bsp_lcd_wr_regno(0xC0);
bsp_lcd_wr_data(0x13);
bsp_lcd_wr_data(0x13);

bsp_lcd_wr_regno(0xC1);
bsp_lcd_wr_data(0x41);

bsp_lcd_wr_regno(0xC5);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x28);
bsp_lcd_wr_data(0x80);

bsp_lcd_wr_regno(0xB1); //Frame rate 70HZ
bsp_lcd_wr_data(0xB0);
bsp_lcd_wr_data(0x11);

bsp_lcd_wr_regno(0xB4);
bsp_lcd_wr_data(0x02);

bsp_lcd_wr_regno(0xB6); //RGB/MCU Interface Control
bsp_lcd_wr_data(0x02); //MCU
bsp_lcd_wr_data(0x22);

bsp_lcd_wr_regno(0xB7);
bsp_lcd_wr_data(0xc6);

bsp_lcd_wr_regno(0xBE);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x04);

bsp_lcd_wr_regno(0xE9);
bsp_lcd_wr_data(0x00);

bsp_lcd_wr_regno(0xF4);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x0f);

bsp_lcd_wr_regno(0xE0);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x04);
bsp_lcd_wr_data(0x0E);
bsp_lcd_wr_data(0x08);
bsp_lcd_wr_data(0x17);
bsp_lcd_wr_data(0x0A);
bsp_lcd_wr_data(0x40);
bsp_lcd_wr_data(0x79);
bsp_lcd_wr_data(0x4D);
bsp_lcd_wr_data(0x07);
bsp_lcd_wr_data(0x0E);
bsp_lcd_wr_data(0x0A);
bsp_lcd_wr_data(0x1A);
bsp_lcd_wr_data(0x1D);
bsp_lcd_wr_data(0x0F);

bsp_lcd_wr_regno(0xE1);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x1B);
bsp_lcd_wr_data(0x1F);
bsp_lcd_wr_data(0x02);
bsp_lcd_wr_data(0x10);
bsp_lcd_wr_data(0x05);
bsp_lcd_wr_data(0x32);
bsp_lcd_wr_data(0x34);
bsp_lcd_wr_data(0x43);
bsp_lcd_wr_data(0x02);
bsp_lcd_wr_data(0x0A);
bsp_lcd_wr_data(0x09);
bsp_lcd_wr_data(0x33);
bsp_lcd_wr_data(0x37);
bsp_lcd_wr_data(0x0F);


bsp_lcd_wr_regno(0xF4);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x00);
bsp_lcd_wr_data(0x0f);

bsp_lcd_wr_regno(0x36);
bsp_lcd_wr_data(0x08);

bsp_lcd_wr_regno(0x3A); //Interface Mode Control
bsp_lcd_wr_data(0x55); //0x66 18bit; 0x55 16bit

bsp_lcd_wr_regno(0x20);
bsp_lcd_wr_regno(0x11);
delay_ms(120);
bsp_lcd_wr_regno(0x29);
delay_ms(50);

}

14.4.5LCD畫點函數(shù)實現(xiàn)

LCD在任意點顯示想要的顏色值,需要設(shè)置顯示光標(biāo)到目標(biāo)位置,然后就可以從該光標(biāo)進(jìn)行顏色數(shù)據(jù)寫入,顏色信息將顯示到LCD的指定坐標(biāo)上。

C
/**
* 說明 畫點
* 輸入 x,y: 坐標(biāo)
* 輸入 color: 點的顏色(32位顏色,方便兼容LTDC)
* 返回值 無
*/
void bsp_8080_lcd_draw_point(uint16_t x, uint16_t y, uint32_t color)
{
if(x>bsp_8080_lcd_parameter.width || y>bsp_8080_lcd_parameter.height)
{
return;
}

if(bsp_8080_lcd_parameter.display_mode == LCD_MODE)
{
bsp_8080_lcd_set_cursor(x, y); /* 設(shè)置光標(biāo)位置 */
EXMC_LCD_C = bsp_8080_lcd_parameter.wramcmd; /* 開始寫入GRAM */
EXMC_LCD_D = color;
}else
{
*(__IO uint16_t*)(((uint32_t)(bsp_8080_lcd_parameter.display_ram)) + 2*((bsp_8080_lcd_parameter.width*y) + x)) = color;
}
}

14.4.6窗口設(shè)置和色塊填充

LCD可以設(shè)置需顯示的窗口,設(shè)置窗口后可以連續(xù)的寫數(shù)據(jù),像素信息會從窗口起始坐標(biāo)開始自動遞增和換行顯示顏色。通過圖塊設(shè)置函數(shù)可以顯示圖片,移植到GUI等;這里我們通過DMA的MEM TO MEM模式可以降低色塊填充過程的CPU占用率,同時提升刷屏速率。

C
/**
* 說明 在指定區(qū)域內(nèi)填充指定顏色塊
* 輸入 (sx,sy),(ex,ey):填充矩形對角坐標(biāo),區(qū)域大小為:(ex - sx + 1) * (ey - sy + 1)
* 輸入 color: 要填充的顏色數(shù)組首地址
* 返回值 無
*/
void bsp_8080_lcd_color_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
{
uint16_t height, width;
if(sx>bsp_8080_lcd_parameter.width || ex>bsp_8080_lcd_parameter.width || sy>bsp_8080_lcd_parameter.height || ey>bsp_8080_lcd_parameter.height)
{
return;
}
// uint32_t i;
width = ex - sx + 1; /* 得到填充的寬度 */
height = ey - sy + 1; /* 高度 */


if(bsp_8080_lcd_parameter.display_mode == LCD_MODE)
{
bsp_8080_lcd_set_window(sx,sy,width,height);
EXMC_LCD_C = bsp_8080_lcd_parameter.wramcmd;
driver_dma_mem_to_exmclcd_start((void*)&EXMC_LCD_D,&color[0],DMA_Width_16BIT,height*width);
// for(uin32_t i = 0; i < height*width; i++)
// {
// EXMC_LCD_D = color[i];
// }
}
else
{
for(uint16_t y = sy; y <= ey; y++)
{
for(uint16_t x = sx; x <= ex; x++)
{
bsp_8080_lcd_parameter.display_ram[y*width+x]=color[(y-sy)*width+(x-sx)];
}
}
}

}

14.4.7字符顯示和LCD Printf

實現(xiàn)上述功能后,通過字庫信息結(jié)合打點函數(shù)就可以實現(xiàn)字符的顯示,我們同時實現(xiàn)了在lcd上打印信息,以printf的形式更輕易便捷的輸出信息到LCD上。

C
/**
* 說明 LCD打印
* 輸入 ...和printf相同用法,自動換行
* 返回值 無
*/
void bsp_8080_lcd_printf(const char * sFormat, ...)
{
#define PRINTF_MAX_LEN 100
char printf_buffer[PRINTF_MAX_LEN];
char* p=printf_buffer;
uint16_t len=0,count=0;
va_list ParamList;
va_start(ParamList, sFormat);
vsprintf(printf_buffer,sFormat, ParamList);
va_end(ParamList);

len=strlen(printf_buffer);

while( ( ((*p <= '~') && (*p >= ' ')) || (*p =='\r') || (*p =='\n') ) && (count {
if((*p =='\r'))
{
bsp_8080_lcd_pritnf_parameter.x_now = bsp_8080_lcd_pritnf_parameter.x_start;
}
else if((*p =='\n'))
{
bsp_8080_lcd_pritnf_parameter.y_now += bsp_8080_lcd_pritnf_parameter.size;
bsp_8080_lcd_fill(bsp_8080_lcd_pritnf_parameter.x_now,bsp_8080_lcd_pritnf_parameter.y_now,bsp_8080_lcd_pritnf_parameter.x_end,bsp_8080_lcd_pritnf_parameter.y_now+bsp_8080_lcd_pritnf_parameter.size,bsp_8080_lcd_pritnf_parameter.back_color);
}
else if( (bsp_8080_lcd_pritnf_parameter.x_now + bsp_8080_lcd_pritnf_parameter.size/2) > bsp_8080_lcd_pritnf_parameter.x_end)
{
bsp_8080_lcd_pritnf_parameter.x_now = bsp_8080_lcd_pritnf_parameter.x_start;
bsp_8080_lcd_pritnf_parameter.y_now += bsp_8080_lcd_pritnf_parameter.size;
bsp_8080_lcd_fill(bsp_8080_lcd_pritnf_parameter.x_now,bsp_8080_lcd_pritnf_parameter.y_now,bsp_8080_lcd_pritnf_parameter.x_end,bsp_8080_lcd_pritnf_parameter.y_now+bsp_8080_lcd_pritnf_parameter.size,bsp_8080_lcd_pritnf_parameter.back_color);
}
else if ( (bsp_8080_lcd_pritnf_parameter.y_now+bsp_8080_lcd_pritnf_parameter.size) > bsp_8080_lcd_pritnf_parameter.y_end)
{
bsp_8080_lcd_pritnf_parameter.x_now = bsp_8080_lcd_pritnf_parameter.x_start;
bsp_8080_lcd_pritnf_parameter.y_now = bsp_8080_lcd_pritnf_parameter.y_start;
bsp_8080_lcd_fill(bsp_8080_lcd_pritnf_parameter.x_start,bsp_8080_lcd_pritnf_parameter.y_start,bsp_8080_lcd_pritnf_parameter.x_end,bsp_8080_lcd_pritnf_parameter.y_end,bsp_8080_lcd_pritnf_parameter.back_color);
}

if((*p !='\r')&&(*p !='\n'))
{
bsp_8080_lcd_show_char(bsp_8080_lcd_pritnf_parameter.x_now, bsp_8080_lcd_pritnf_parameter.y_now, *p, bsp_8080_lcd_pritnf_parameter.size, 0, bsp_8080_lcd_pritnf_parameter.point_color,bsp_8080_lcd_pritnf_parameter.back_color);
bsp_8080_lcd_pritnf_parameter.x_now += bsp_8080_lcd_pritnf_parameter.size / 2;
}
p++;
count++;
}

}

14.4.8主函數(shù)

主函數(shù)如下所示,進(jìn)入主函數(shù)后,首先進(jìn)行驅(qū)動初始化,包括串口、LED、以及8080接口LCD初始化,之后顯示log圖片以及字符串信息,進(jìn)入主循環(huán)后,循環(huán)顯示當(dāng)前系統(tǒng)tick。

C
int main(void)
{
uint64_t tick_temp=0;
uint16_t frames_speed=0;

driver_init(); /* 延時和公共驅(qū)動部分初始化 */
bsp_uart_init(&BOARD_UART); /* 打印串口初始化 */

bsp_led_group_init(); /* 初始化LED組 */
bsp_led_on(&LED1);
bsp_led_off(&LED2);

delay_ms(100);
printf("TFT 8080 LCD examples.\r\n");

bsp_8080_lcd_init(); /* 初始化LCD */

//計算刷整屏速度
tick_temp=driver_tick;
bsp_8080_lcd_clear(WHITE);
frames_speed=driver_tick-tick_temp;

//顯示log圖片
bsp_8080_lcd_color_fill(60,0,233,99,(uint16_t*)gd_log_picture);

//設(shè)置打印窗口
bsp_8080_lcd_printf_init(10,109,bsp_8080_lcd_parameter.width-1,369,FONT_ASCII_24_12,WHITE,BLUE);

//打印到LCD
bsp_8080_lcd_printf("GD32H757ZMT6\r\n");
bsp_8080_lcd_printf("EXMC LCD Brush Test\r\n");
bsp_8080_lcd_printf("LCD ID:%04X\r\n", bsp_8080_lcd_parameter.id);
bsp_8080_lcd_printf("* Suzhou Juwo Electronic\r\n");
bsp_8080_lcd_printf("* web: www.gd32bbs.com\r\n");
bsp_8080_lcd_printf("* B station: 475462605\r\n");
bsp_8080_lcd_printf("* QQ Group: 859440462\r\n");
bsp_8080_lcd_printf("* Taobao: juwo.taobao.com\r\n");
bsp_8080_lcd_printf("* Official ID: gd32bbs\r\n");
bsp_8080_lcd_printf("frames brush:%d ms\r\n", frames_speed);

//重新設(shè)置新的打印窗口
bsp_8080_lcd_printf_init(0,370,bsp_8080_lcd_parameter.width-1,bsp_8080_lcd_parameter.height-1,FONT_ASCII_12_6,BLUE,~BLUE);

//將搖桿采集結(jié)果處理控制LCD亮度
bsp_8080_lcd_backlight_duty_set(90);
while (1)
{
bsp_8080_lcd_printf(" ");
//打印系統(tǒng)tick到LCD
bsp_8080_lcd_printf("* system tic is %lld \r\n",driver_tick);
delay_ms(200);
}
}

14.5實驗結(jié)果

復(fù)位后顯示聚沃和GD LOG圖片,大字顯示LCD ID,刷屏?xí)r間、聚沃相關(guān)鏈接地址等。在下方設(shè)置了一個printf區(qū)窗口,循環(huán)打印亮度信息和系統(tǒng)tic信息。

教程GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關(guān)注聚沃科技官網(wǎng)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6030

    文章

    44489

    瀏覽量

    631958
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    16885

    瀏覽量

    349912
  • 嵌入式
    +關(guān)注

    關(guān)注

    5059

    文章

    18973

    瀏覽量

    301995
  • 開發(fā)板
    +關(guān)注

    關(guān)注

    25

    文章

    4895

    瀏覽量

    97055
  • GD32
    +關(guān)注

    關(guān)注

    7

    文章

    403

    瀏覽量

    24106
收藏 人收藏

    評論

    相關(guān)推薦

    GD32H757Z海棠開發(fā)板使用手冊第十三講 SDIO-SD卡讀寫實驗

    通過本實驗主要學(xué)習(xí)以下內(nèi)容: ?USB協(xié)議基本原理 ?GD32H7xx USBHS的使用 ?虛擬鍵盤的協(xié)議原理及使用
    的頭像 發(fā)表于 06-06 11:26 ?1698次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>】<b class='flag-5'>第十</b>三講 SDIO-SD卡讀寫實驗

    液晶顯示模塊使用手冊-中文PDF

    液晶顯示模塊使用手冊-中文PDF 
    發(fā)表于 10-10 10:13

    點陣字符型液晶顯示模塊 使用手冊LCD1602

    點陣字符型液晶顯示模塊 使用手冊
    發(fā)表于 05-25 13:57

    迅為iMX6ULL開發(fā)板使用手冊資料下載

    的知識點,它都有!《嵌入式Linux開發(fā)指南》+《開發(fā)板使用手冊》+《裸機使用手冊》鏈接:https://pan.baidu.com/s/1Xat4C-cDa2Gi1UwNckNRTw
    發(fā)表于 12-02 14:13

    點陣字符型液晶顯示模塊使用手冊

    點陣字符型液晶顯示模塊使用手冊有點陣字符型液晶顯示模塊的基本特點,MDLS字符型液晶顯示模塊特性,MDLS字符型液晶顯示模塊指令集,MDLS
    發(fā)表于 11-01 10:39 ?11次下載
    點陣字符型<b class='flag-5'>液晶顯示</b>模塊<b class='flag-5'>使用手冊</b>

    第十四講 555定時器

    第十四講 555定時器 5.5.1 555定時器的電路結(jié)構(gòu)及其功能 一、結(jié)構(gòu)框圖(圖5.5.1 雙極型)1.
    發(fā)表于 03-30 16:20 ?3855次閱讀
    <b class='flag-5'>第十四講</b> 555定時器

    YL-51開發(fā)板使用手冊

    YL-51開發(fā)板使用手冊,YL-51開發(fā)板使用手冊YL-51開發(fā)板使用手冊YL-51
    發(fā)表于 05-10 16:31 ?21次下載

    字符型液晶顯示模塊使用手冊

    電子發(fā)燒友網(wǎng)站提供《字符型液晶顯示模塊使用手冊.pdf》資料免費下載
    發(fā)表于 10-08 09:29 ?0次下載
    字符型<b class='flag-5'>液晶顯示</b>模塊<b class='flag-5'>使用手冊</b>

    RA8835液晶顯示模塊使用手冊

    電子發(fā)燒友網(wǎng)站提供《RA8835液晶顯示模塊使用手冊.pdf》資料免費下載
    發(fā)表于 01-02 10:03 ?1次下載

    GD32H757Z海棠開發(fā)板使用手冊】第八講 ADC-規(guī)則組多通道采樣實驗

    通過本實驗主要學(xué)習(xí)以下內(nèi)容: ADC的簡介 GD32FH757 ADC工作原理 DMA和DMAMUX的原理 規(guī)則組多通道循環(huán)采樣
    的頭像 發(fā)表于 05-14 09:39 ?556次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>】第八講 ADC-規(guī)則組多通道采樣實驗

    GD32H757Z海棠開發(fā)板使用手冊】第九講 USART-printf打印實驗

    通過本實驗主要學(xué)習(xí)以下內(nèi)容: ?串口簡介 ?GD32H757工作原理 ?使用printf打印信息
    的頭像 發(fā)表于 05-15 11:39 ?602次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>】第九講 USART-printf打印實驗

    GD32H757Z海棠開發(fā)板使用手冊第十一講 SPI-SPI NOR FLASH讀寫實驗

    通過本實驗主要學(xué)習(xí)以下內(nèi)容: ?SPI簡介 ?GD32H7 SPI簡介 ?SPI NOR FLASH——GD25Q128ESIGR簡介 ?使用GD32H7 SPI接口實現(xiàn)對GD25Q1
    的頭像 發(fā)表于 06-04 11:42 ?785次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>】<b class='flag-5'>第十</b>一講 SPI-SPI NOR FLASH讀寫實驗

    GD32F303紅楓開發(fā)板使用手冊】第二十講 SPI-SPI NAND FLASH讀寫實驗

    通過本實驗主要學(xué)習(xí)以下內(nèi)容: ?SPI通信協(xié)議,參考19.2.1東方紅開發(fā)板使用手冊 ?GD32F303 SPI操作方式,參考19.2.2東方紅開發(fā)板
    的頭像 發(fā)表于 06-20 09:50 ?731次閱讀
    【<b class='flag-5'>GD</b>32F303紅楓<b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>】第二十講 SPI-SPI NAND FLASH讀寫實驗

    【北京迅為】iTOP-i.MX6開發(fā)板使用手冊第四部分固件編譯第十四章非設(shè)備樹Android4.4系統(tǒng)編譯

    【北京迅為】iTOP-i.MX6開發(fā)板使用手冊第四部分固件編譯第十四章非設(shè)備樹Android4.4系統(tǒng)編譯
    的頭像 發(fā)表于 09-12 15:43 ?367次閱讀
    【北京迅為】iTOP-i.MX6<b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>第四部分固件編譯<b class='flag-5'>第十四</b>章非設(shè)備樹Android4.4系統(tǒng)編譯

    GD32H757Z海棠開發(fā)板使用手冊第十五講 TFT-8080電阻屏屏觸摸實驗

    通過本實驗主要學(xué)習(xí)以下內(nèi)容: LCD觸控原理 SPI外設(shè)功能
    的頭像 發(fā)表于 09-19 09:30 ?263次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊</b>】<b class='flag-5'>第十</b>五講 <b class='flag-5'>TFT-8080</b>電阻屏屏觸摸實驗