【GD32F303紅楓派使用手冊】第二十六節 EXMC-液晶驅動實驗

26.1 實驗內容

通過本實驗主要學習以下內容:

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

26.2 實驗原理

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

26.2.1 TFT-LCD介紹

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

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

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

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

GD32F3紅楓派開發板TFT-LCD如下圖所示,采用了ILI9488 LCD驅動器,分辨率320*480,支持多種通信接口,在GD32F303xx上,適合使用16-bit Parallel MCU Interface接口進行通信,開發板配套的LCD模塊也采用了該接口設計和開發板進行連接。

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

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

  • 如下圖所示是16-bit Parallel MCU Interface的接口和MCU的連接信號:

  • 如下圖所示是LCD驅動器 16BIT 8080并口讀寫時序:
  • CS拉低后,并口DATA IO在WR的上升沿被采樣;
  • 可以理解為16線的SPI,而WR是寫“CLK”,RD是讀“CLK”;
  • 但這里還多了D/C引腳用于選擇傳輸命令或數據

  • 8080接口的RGB顏色數據編碼
  • 像素信息用RGB三原色表示,所以向液晶屏傳輸的數據幀主要也就是傳輸的RGB顏色數據。
  • 像素的顏色數據并不總是用 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顏色數據編碼。
  • 綜合顯示效果、內存資源開銷等,我們采取了RGB565像素格式,這樣16BIT 8080每次傳輸就是一個像素點的像素值,傳輸數據就為像素顏色值。

26.2.3 EXMC外設和EXMC NOR/SRAM模式實現8080時序

  • 這里我們使用EXMC中時序和接口類似的NOR/SRAM模式,來實現8080接口驅動TFT-LCD顯示,EXMC外設可參考上文介紹東方紅開發板使用手冊?,EXMC NOR/SRAM模式可參考上文介紹東方紅開發板使用手冊?
  • 這里我們使用SRAM模式異步模式A(擴展模式),時序如下圖:

我們對比上面的時序和16-bit Data Bus 8080 LCD時序,發現一些信號的時序是類似的,我們可以將這些信號進行對應:

EXMC_NEx -> CSx

EXMC_NOE->RDx

EXMC_NWE->WR

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

EXMC_Ax->D/C

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

26.3 硬件設計

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

LCD在顯示過程電源電流會有變化,為了穩定電源我們在3.3V和5V接口上使用了1uf電容。

26.4 代碼解析

26.4.1 CSx、D/C、BL相關功能定義和注冊;

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

C
//定義背光引腳的PWM通道和GPIO
TIMER_CH_DEF(LCD_BL,TIMER12,0,TIMER_CH_PWM_HIGH,F,8,AF_PP,GPIO_TIMER12_REMAP);//定義使用的EXMC_Ax引腳
#define EXMC_Ax  12
GPIO_DEF(EXMC_Ax_GPIO,G,2,AF_PP,SET,NULL);//定義使用的EXMC_NEx引腳
#define EXMC_NEx 1
GPIO_DEF(EXMC_NEx_GPIO,D,7,AF_PP,SET,NULL);//LCD數據、命令地址轉換
#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))))

26.4.2 gpio和exmc初始化:

exmc使用了擴展模式,這樣讀和寫的時序可以單獨配置,因為LCD對讀和寫的要求時間是不同的,讀的時候速率不能太高,如果使用一種參數類型就會為了滿足讀的要求而降低寫的速率,影響最終刷屏的性能。這里主要調整讀和寫時的地址建立、數據建立時間,通常和硬件設計也有較大關系,這里紅楓派開發板和配套LCD的電路可以在120M主頻下,設置讀數據建立5個clk、地址建立1個clk,寫數據建立2個clk,地址建立1個clk。

C
/*!
* 說明     emxc LCD模式通用gpio初始化
* 輸入[1]  norsram_region: @EXMC_BANK0_NORSRAM_REGION0/EXMC_BANK0_NORSRAM_REGION1/EXMC_BANK0_NORSRAM_REGION2/EXMC_BANK0_NORSRAM_REGION3
* 返回值   無
*/
void driver_exmc_lcd_16bit_gpio_init(void)
{/* EXMC clock enable */rcu_periph_clock_enable(RCU_EXMC);/* GPIO clock enable */rcu_periph_clock_enable(RCU_GPIOD);rcu_periph_clock_enable(RCU_GPIOE);rcu_periph_clock_enable(RCU_GPIOG);rcu_periph_clock_enable(RCU_AF);    /* configure EXMC_D[0~15]*//* PD14(EXMC_D0), PD15(EXMC_D1),PD0(EXMC_D2), PD1(EXMC_D3), PD8(EXMC_D13), PD9(EXMC_D14), PD10(EXMC_D15) */gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_MAX, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_8 | GPIO_PIN_9 |GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);/* PE7(EXMC_D4), PE8(EXMC_D5), PE9(EXMC_D6), PE10(EXMC_D7), PE11(EXMC_D8), PE12(EXMC_D9), PE13(EXMC_D10), PE14(EXMC_D11), PE15(EXMC_D12) */gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_MAX, 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 PE2(EXMC_Ax) */ 
//    gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_MAX, GPIO_PIN_2);/* configure NOE and NWE */gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_MAX, GPIO_PIN_4 | GPIO_PIN_5);//    /* configure EXMC NEx */
//    gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_MAX, GPIO_PIN_7);gpio_compensation_config(GPIO_COMPENSATION_ENABLE);while(gpio_compensation_flag_get()==RESET);
}/*!
* 說明     emxc LCD模式初始化
* 輸入[1]  norsram_region: @EXMC_BANK0_NORSRAM_REGION0/EXMC_BANK0_NORSRAM_REGION1/EXMC_BANK0_NORSRAM_REGION2/EXMC_BANK0_NORSRAM_REGION3
* 返回值   無
*/
void driver_exmc_lcd_init(uint32_t norsram_region)
{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;/* EXMC clock enable */rcu_periph_clock_enable(RCU_EXMC);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);/* 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 = 5;nor_timing_read_init_struct.asyn_address_holdtime = 1;nor_timing_read_init_struct.asyn_address_setuptime = 1;/* 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 = 2;nor_timing_write_init_struct.asyn_address_holdtime = 1;nor_timing_write_init_struct.asyn_address_setuptime = 1;    /* 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);  
}

?26.4.3 LCD數據、命令讀寫:

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

C
/*** 說明       LCD寫數據* 輸入       data: 要寫入的數據* 返回值      無*/
void bsp_lcd_wr_data(__IO uint16_t data)
{//delay_sysclk(1);            EXMC_LCD_D = data;
}/*** 說明       LCD寫寄存器編號/地址函數* 輸入       regno: 寄存器編號/地址* 返回值      無*/
void bsp_lcd_wr_regno(__IO uint16_t regno)
{//delay_sysclk(1);        EXMC_LCD_C = regno;   /* 寫入要寫的寄存器序號 */
}/*** 說明       LCD寫寄存器* 輸入       regno:寄存器編號/地址* 輸入       data:要寫入的數據* 返回值      無*/
void bsp_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;    /* 寫入數據 */
}/*** 說明       LCD讀數據* 輸入       無* 返回值      讀取到的數據*/
static uint16_t bsp_lcd_read_data(void)
{//delay_sysclk(1);return EXMC_LCD_D;
}

26.4.4 LCD初始化

LCD初始化序列通常LCD驅動器廠家會提供相關寄存器配置,為了兼容不同的LCD,可以讀取LCD ID后執行不同的驅動芯片初始化,初始化過程的寄存器配置就通過25.4.3章節實現的命令、數據讀寫接口實現:

C
/*** 說明       初始化LCD*   @note      該初始化函數可以初始化各種型號的LCD(詳見本.c文件最前面的描述)** 輸入       無* 返回值      無*/
uint32_t bsp_lcd_init(void)
{bsp_lcd_port_init();bsp_lcd_backlight_duty_set(BACK_LIGHT_DUTY);bsp_lcd_backlight_on();          /* 點亮背光 */    /* LCD的畫筆顏色和背景色 */bsp_lcd_parameter.g_point_color = WHITE;    /* 畫筆顏色 */bsp_lcd_parameter.g_back_color  = BLACK;    /* 背景色 */    delay_ms(1);     /* 初始化FSMC后,必須等待一定時間才能開始初始化 *//* 嘗試9341 ID的讀取 */bsp_lcd_wr_regno(0XD3);bsp_lcd_parameter.id = bsp_lcd_read_data();  /* dummy read */bsp_lcd_parameter.id = bsp_lcd_read_data();  /* 讀到0X00 */bsp_lcd_parameter.id = bsp_lcd_read_data();  /* 讀取0X93 */bsp_lcd_parameter.id <<= 8;bsp_lcd_parameter.id |= bsp_lcd_read_data(); /* 讀取0X41 */if (bsp_lcd_parameter.id == 0X9488){lcd_ex_ili9488_reginit();   /* 執行ILI9388初始化 */}     else if (bsp_lcd_parameter.id == 0X9341){lcd_ex_ili9341_reginit();   /* 執行ILI9341初始化 */}else{return DRV_ERROR;}bsp_lcd_display_dir(0); /* 默認為豎屏 */bsp_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); } 

26.4.5 LCD畫點函數實現

LCD在任意點顯示想要的顏色值,需要設置顯示光標到目標位置,然后就可以從該光標進行顏色數據寫入,顏色信息將顯示到LCD的指定坐標上。

C
/*** 說明       畫點* 輸入       x,y: 坐標* 輸入       color: 點的顏色(32位顏色,方便兼容LTDC)* 返回值      無*/
void bsp_lcd_draw_point(uint16_t x, uint16_t y, uint32_t color)
{bsp_lcd_set_cursor(x, y);       /* 設置光標位置 */EXMC_LCD_C = bsp_lcd_parameter.wramcmd;    /* 開始寫入GRAM */EXMC_LCD_D = color;
}

26.4.6 窗口設置和色塊填充

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

C
/*** 說明       在指定區域內填充指定顏色塊* 輸入       (sx,sy),(ex,ey):填充矩形對角坐標,區域大小為:(ex - sx + 1) * (ey - sy + 1)* 輸入       color: 要填充的顏色數組首地址* 返回值      無*/
void bsp_lcd_color_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
{uint16_t height, width;
//    uint32_t i;width = ex - sx + 1;            /* 得到填充的寬度 */height = ey - sy + 1;           /* 高度 */bsp_lcd_set_window(sx,sy,width,height);EXMC_LCD_C = bsp_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];     
//    }
}

26.4.7 字符顯示和LCD Printf

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

C
/*** 說明       LCD打印* 輸入       ...和printf相同用法,自動換行* 返回值      無*/
void bsp_lcd_printf(const char * sFormat, ...) 
{char printf_buffer[64];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<len) )   /* 判斷是不是非法字符! */{if((*p =='\r')){bsp_lcd_pritnf_parameter.x_now = bsp_lcd_pritnf_parameter.x_start;}        else if((*p =='\n')){bsp_lcd_pritnf_parameter.y_now += bsp_lcd_pritnf_parameter.size; bsp_lcd_fill(bsp_lcd_pritnf_parameter.x_now,bsp_lcd_pritnf_parameter.y_now,bsp_lcd_pritnf_parameter.x_end,bsp_lcd_pritnf_parameter.y_now+bsp_lcd_pritnf_parameter.size,bsp_lcd_pritnf_parameter.back_color);            }else if( (bsp_lcd_pritnf_parameter.x_now + bsp_lcd_pritnf_parameter.size/2) > bsp_lcd_pritnf_parameter.x_end){bsp_lcd_pritnf_parameter.x_now = bsp_lcd_pritnf_parameter.x_start;bsp_lcd_pritnf_parameter.y_now += bsp_lcd_pritnf_parameter.size;bsp_lcd_fill(bsp_lcd_pritnf_parameter.x_now,bsp_lcd_pritnf_parameter.y_now,bsp_lcd_pritnf_parameter.x_end,bsp_lcd_pritnf_parameter.y_now+bsp_lcd_pritnf_parameter.size,bsp_lcd_pritnf_parameter.back_color);                        }else if ( (bsp_lcd_pritnf_parameter.y_now+bsp_lcd_pritnf_parameter.size) > bsp_lcd_pritnf_parameter.y_end){bsp_lcd_pritnf_parameter.x_now = bsp_lcd_pritnf_parameter.x_start;bsp_lcd_pritnf_parameter.y_now = bsp_lcd_pritnf_parameter.y_start;            bsp_lcd_fill(bsp_lcd_pritnf_parameter.x_start,bsp_lcd_pritnf_parameter.y_start,bsp_lcd_pritnf_parameter.x_end,bsp_lcd_pritnf_parameter.y_end,bsp_lcd_pritnf_parameter.back_color);}if((*p !='\r')&&(*p !='\n')){bsp_lcd_show_char(bsp_lcd_pritnf_parameter.x_now, bsp_lcd_pritnf_parameter.y_now, *p, bsp_lcd_pritnf_parameter.size, 0, bsp_lcd_pritnf_parameter.point_color,bsp_lcd_pritnf_parameter.back_color);bsp_lcd_pritnf_parameter.x_now += bsp_lcd_pritnf_parameter.size / 2;            }p++;count++;}}

26.5 實驗結果

復位后顯示聚沃和GD LOG圖片,大字顯示LCD ID,刷屏時間、聚沃相關鏈接地址等。在下方設置了一個printf區窗口,循環打印亮度信息和系統tic信息。左右波動搖桿可以調節LCD亮度。

由聚沃科技原創,來源于

?【紅楓派開發板】第二十六講 EXMC-液晶驅動實驗 - 蘇州聚沃電子科技有限公司 (gd32bbs.com)

??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35397.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35397.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35397.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圖像超分辨率重建

一、什么是圖像超分辨 圖像超分辨是一種技術&#xff0c;旨在通過硬件或軟件的方法提高原有圖像的分辨率。這一過程涉及從一系列低分辨率的圖像中獲取一幅高分辨率的圖像&#xff0c;實現了時間分辨率向空間分辨率的轉換。超分辨率重建的核心思想是利用多幀圖像序列的時間帶寬來…

計算機畢業設計Thinkphp/Laravel學生考勤管理系統zyoqy

管理員登錄學生考勤管理系統后&#xff0c;可以對首頁、個人中心、公告信息管理、年級管理、專業管理、班級管理、學生管理、教師管理、課程信息管理、學生選課管理、課程簽到管理、請假申請管理、銷假申請管理等功能進行相應操作&#xff0c;如圖5-2所示。學生登錄進入學生考勤…

金蝶云蒼穹考試題目大全

前言 受不了某些地方看個答案還要收費&#xff0c;總結多份試卷 題目有重復&#xff0c;關鍵字檢索即可 試卷一 金蝶云蒼穹考試題目大全 單選題 開發知識錯題反饋1.0分 1.關于編碼規則的適用范圍說法錯誤的是 A.單據沒有設置主業務組織的情況下&#xff0c;則校驗用戶當前登…

【Spine學習16】之 人物面部綁定

1、創建頭部骨骼 一根頭骨 以頭骨為父結點創建一個面部控制器face-holder 2、創建頭發和face面部控制結點的變換約束 左右頭發的約束指向為face結點 3、設定后發的變換約束&#xff0c;約束指向為face結點&#xff0c;反方向移動 設置參數為-100 同理&#xff0c;耳朵也依…

C# 中的 App.manifest 文件:優化應用程序配置與權限管理

前言 在開發 C# 應用程序時&#xff0c;可能會忽略一個重要的文件——App.manifest。這個文件看似不起眼&#xff0c;卻在應用程序的運行和用戶體驗上扮演著關鍵角色。了解和正確配置 App.manifest 文件&#xff0c;不僅可以確保應用程序在不同操作系統上的兼容性&#xff0c;…

解決uniapp,textarea拉起頁面被頂起和鍵盤被輸入框遮擋的問題。

1&#xff1a;Android、ios 同時解決&#xff1b; 2&#xff1a;我們在開發的時候會發現textarea或者input拉起鍵盤的時候整個頁面被頂起了&#xff0c;header也被頂沒了&#xff1b;官方給了:adjustPositionfalse屬性&#xff0c;設置完之后頁面就不會被頂起&#xff0c;但是…

談談SQL優化

SQL優化是數據庫性能優化中的關鍵環節&#xff0c;旨在提高查詢執行的效率和響應速度。下面是一些常見的SQL優化技巧和策略&#xff0c;涵蓋索引、查詢設計、表結構設計等方面&#xff1a; 1. 索引優化 創建索引&#xff1a;為常用查詢的過濾條件&#xff08;WHERE 子句&…

了解json

一.什么是json 1.什么是json是一種輕量級的數據交互&#xff0c;可以按照指定的json格式去組織和封裝數據 2.json本質上是一個帶有特定格式的字符串 二.json主要功能&#xff1a;json就是一種在各個編程語言中流通的數據格式&#xff0c;負責不同語言中的數據傳遞和交互&…

【Python時序預測系列】基于CNN+Bi-LSTM實現單變量時間序列預測(案例+源碼)

這是我的第309篇原創文章。 一、引言 基于CNN&#xff08;卷積神經網絡&#xff09;和Bi-LSTM&#xff08;雙向長短期記憶網絡&#xff09;的單變量時間序列預測是一種結合空間特征提取和時間依賴建模的方法。以下是一個基于Python和TensorFlow/Keras實現的示例&#xff0c;展…

C++ 高頻面試題

C 初級面試題及其詳細解答 1. 解釋 C 中的基本數據類型。 解答&#xff1a; C 提供了幾種基本數據類型&#xff0c;包括&#xff1a; int&#xff1a;整型&#xff0c;用于存儲整數。float 和 double&#xff1a;浮點型&#xff0c;用于存儲小數。char&#xff1a;字符型&am…

Android 強制使用移動網絡訪問接口

Android 強制使用移動網絡訪問接口_安卓連接wifi強制使用移動數據-CSDN博客 Android應用層實現恢復出廠設置功能_android7 intent 打開恢復出廠設置-CSDN博客

YOLOv8改進 | 主干網絡| 可變形卷積網絡C2f_DCN【CVPR2017】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本專欄所有程序均經過測試&#xff0c;可成功執行&#x1f4a1;&#x1f4a1;&#x1f4a1; 專欄目錄&#xff1a;《YOLOv8改進有效漲點》專欄介紹 & 專欄目錄 | 目前已有40篇內容&#xff0c;內含各種Head檢測頭、損失函數Loss、B…

java SQL server 多實例的情況

而對于java&#xff0c;對付多個數據庫實例就有些要注意的了&#xff1a; 首先&#xff0c;同樣連接字符串上加上“\實例名”&#xff1a; jdbc:sqlserver://127.0.0.1\\mssqlserver2008;DatabaseNameLPT; 此處應去掉端口1433。因為連接數據庫自命名實例的url中沒有端口號1433…

SiLM585x系列SiLM5851NHCG-DG一款具有分離的管腳輸出 單通道隔離驅動器 擁有強勁的驅動能力

SiLM585x系列SiLM5851NHCG-DG是一款單通道隔離驅動器&#xff0c;具有分離的管腳輸出&#xff0c;提供3.0A源電流和6.0A灌電流。主動保護功能包括退飽和過流檢測、UVLO、隔離故障報警和 2.5A 米勒鉗位。輸入側電源的工作電壓為3V至5.5V&#xff0c;輸出側電源的工作電壓范圍為1…

獨孤思維:研發的新賺錢項目,活脫脫掉了幾層皮

01 今天有個讀者問我&#xff0c;xx項目&#xff0c;成功概率多少&#xff1f; 其實這和做這個項目&#xff0c;能賺多少錢&#xff0c;本質是一個問題。 即&#xff0c;有多大的確定性。 言外之意&#xff0c;沒有確定性&#xff0c;不穩定&#xff0c;我就不做了。 可以…

一位軟件測試工程師繁忙的一天

早晨&#xff1a;啟動一天的工作 7:00 AM - 起床 早晨七點準時起床。洗漱、早餐后&#xff0c;檢查了手機上的郵件和消息&#xff0c;了解今天的工作安排和優先事項。 8:00 AM - 前往公司 乘坐地鐵前往公司。在地鐵上&#xff0c;他習慣性地閱讀一些技術博客&#xff0c;了解…

小柴沖刺嵌入式系統設計師系列總目錄

工作兩年 逐漸意識到基礎知識的重要性?? 意識到掌握了這個證書好像就已經掌握了80%工作中用到的知識了。剩下的就在工作的實戰中學習 來和小柴一起沖刺軟考吧&#xff01;加油&#x1f61c; 【小柴沖刺軟考中級嵌入式系統設計師系列】總目錄 前言 專欄目標&#xff1a;沖刺…

涵蓋多項功能的文件外發系統,了解一下

伴隨著業務范圍的不斷擴大&#xff0c;信息化的迅速發展&#xff0c;企業與客戶、供應商等合作伙伴之間的文件交換也愈加頻繁&#xff0c;尤其涉及到核心數據&#xff0c;像核心技術、設計圖紙等敏感數據&#xff0c;對其的保護也是越發重視。文件外發系統&#xff0c;應運而生…

Linux基礎 - RAID 與 LVM 磁盤陣列技術

目錄 零. 簡介 一. RAID 二. LVM 三. 總結 零. 簡介 在 Linux 中&#xff0c;RAID&#xff08;Redundant Array of Independent Disks&#xff0c;獨立磁盤冗余陣列&#xff09;和 LVM&#xff08;Logical Volume Manager&#xff0c;邏輯卷管理器&#xff09;是兩種常用的…

機械繼電器、固態繼電器和模擬開關對比分析

1 結構 2 長期可靠性 與機械繼電器相比&#xff0c;光繼電器明顯提高了可靠性&#xff0c;因為沒有活動器件。 光繼電器通過 LED 進行光學控制。通常情況下&#xff0c;此 LED 會隨著時間的推移比開關本身更快地降級&#xff0c;具體取決于溫度、正向電流、開關速度等。隨著 LE…