【GD32450I-EVAL】+ 04 LCD screen stacking display and transparency adjustment test
[Copy link]
This post was last edited by DDZZ669 on 2020-9-20 15:44
The previous article " 【GD32450I-EVAL】+ 03 Basic usage of library functions - taking key interrupt as an example " introduced the basic usage of GD32 library development. This article will study the LCD display.
1 RGB LCD screen
The GD32450I development board comes with a 4.3-inch 480x272 RGB interface display screen, which is a TFT-LCD (Thin Film Transistor-Liquid Crystal Display) type.
I have only used screens with MCU interfaces before, so here are the differences:
- MCU-LCD : It was originally designed for microcontrollers (MCUs). Because the memory of a microcontroller is small, the video memory is built into the LCD module. The video memory is updated through special display commands, and the MCU screen cannot be made very large. The MCU screen displays images, and the display needs to send a dot-drawing command to modify the MCU's internal RAM.
- RGB-LCD : Its video memory is played by the system memory. As long as the system memory is large enough, the RGB-LCD can be made larger. To display images on the RGB screen, the video memory only needs to organize the data. After starting the display, the LCD-DMA will automatically send the video memory to the display screen through the RGB interface, so the refresh speed of the RGB screen is faster.
The working diagrams of the two screens are as follows:
Two driving modes for the screen:
RGB screens generally have two driving modes: DE mode and SYNC mode (or HV mode). DE mode uses DE signal to determine valid data, while SYNC mode requires line synchronization (Hsync) and field synchronization (Vsync) to indicate the scanned rows and columns.
Some parameters about the screen:
It can be seen that although the screen resolution is 480*272, the total horizontal and vertical period will be greater than this number. You don’t need to worry about the specific function of the extra pixels on the edge. These numbers will be used when the screen is initialized in the program. Just know how to correspond them.
2 TLI of GD32
TLI (TFT-LCD Interface) is a liquid crystal interface, which is a control interface provided by the GD32 microcontroller itself to drive RGB-LCD. TLI supports two independent display layers, and supports layer window and layer aliasing functions. The cascade display process is shown in the figure below:
In this figure, layer 0 and layer 1 are two independent display layers. In addition, there is a BG layer , which is the background layer. You can specify a certain color to display. This layer is at the bottom. Layer 0 is superimposed on the BG layer. By adjusting the transparency of layer 0, it can be displayed in a fusion with the BG layer. Layer 1 is superimposed on the top, and the transparency can also be adjusted. The three layers are superimposed together to form the effect displayed on the screen.
3 Image to RGB565
This LCD supports multiple pixel formats, as shown in the following table. This test first uses the RGB565 format, that is, red, green, and blue occupy 5, 6, and 5 bits respectively to represent the color value, so it takes 16 bits to describe a color pixel, that is, 2 bytes, or one word.
The image is converted into RGB565 hexadecimal data . You can use some small tools to convert it and save it into an array after conversion.
The conversion method is as follows: first find a picture you need, then use the small software Picture2Hex, specify the width and height of the converted picture, select the picture conversion, and then generate a logo.c file, and put the array in the file into your own code project for use.
4 Layering and transparency display test
The above introduces some basic principles. Let's write a test program to see the effect of cascading display.
First is the main function part , which is various initializations. Finally, the color or transparency of the three layers will be changed in the key interrupt:
int main(void)
{
system_clock_config();
systick_config();
mytimer_init();
key_config();//通过按键来改变3个层的颜色或透明度
lcd_init();//LCD的GPIO等的初始化
lcd_layer_init();//LCD的显示层的初始化
tli_layer_enable(LAYER0);
tli_layer_enable(LAYER1);
tli_enable();//使能两个显示层
//设置两个显示层的透明度
lcd_layer_set(LCD_LAYER_FOREGROUND);
lcd_transparency_set(125);//0~255
lcd_layer_set(LCD_LAYER_BACKGROUND);
lcd_transparency_set(155);//0~255
while (1)
{
//主循环,什么也不做,在按键中断中会只改变透明度
}
}
The initialization part mainly looks at the initialization of LCD and the initialization of layers.
First look at the initialization of the LCD :
void lcd_init(void)
{
//--------此处省去GPIO、时钟等的初始化
/* TLI initialization */
tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW;
tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW;
tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW;
tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI;
/* LCD display timing configuration */
tli_init_struct.synpsz_hpsz = 40;
tli_init_struct.synpsz_vpsz = 9;
tli_init_struct.backpsz_hbpsz = 42;
tli_init_struct.backpsz_vbpsz = 11;
tli_init_struct.activesz_hasz = 522;
tli_init_struct.activesz_vasz = 283;
tli_init_struct.totalsz_htsz = 524;
tli_init_struct.totalsz_vtsz = 285;
/* LCD background color configure*/ //最底层
tli_init_struct.backcolor_red = 0xFF;
tli_init_struct.backcolor_green = 0xFF;
tli_init_struct.backcolor_blue = 0xFF;
tli_init(&tli_init_struct);
}
In Part 1, the DE parameter is Low, so the SYNC mode is used.
In Part 2, there are many parameters, you can first refer to the screen parameter table above.
In the second part, the "BG layer" in the overlay layer, that is, the bottom layer, is first given 0xFF, which is white.
Let's look at the initialization of the layer:
void lcd_layer_init(void)
{
tli_layer_parameter_struct tli_layer_init_struct;
/* TLI layer1 configuration */ //layer1 前景层(最上层)
tli_layer_init_struct.layer_window_leftpos = (0 + 43);//最左侧从0开始
tli_layer_init_struct.layer_window_rightpos = (0 + 400 + 43 - 1); //最右侧到400结束
tli_layer_init_struct.layer_window_toppos = (0 + 12);//最上侧从0开始
tli_layer_init_struct.layer_window_bottompos = (0 + 200 + 12 - 1);//最下侧到200结束
tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;//RGB565格式
tli_layer_init_struct.layer_sa = 0x0;//其余部分透明显示
tli_layer_init_struct.layer_default_blue = 0xFF;
tli_layer_init_struct.layer_default_green = 0xFF;
tli_layer_init_struct.layer_default_red = 0xFF;
tli_layer_init_struct.layer_default_alpha = 0x0;//图片部分的透明度,之后可以通过按键修改
tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA;//LAYER_ACF1_SA;
tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA;//LAYER_ACF2_SA;
tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)image_eeworld;//eeworld图片的RGB565数组
tli_layer_init_struct.layer_frame_line_length = ((LCD_PIXEL_WIDTH * 2) + 3);
tli_layer_init_struct.layer_frame_buf_stride_offset = (LCD_PIXEL_WIDTH * 2);
tli_layer_init_struct.layer_frame_total_line_number = LCD_PIXEL_HEIGHT;
tli_layer_init(LAYER1, &tli_layer_init_struct);
/* TLI layer0 configuration */ //layer0 背景层(中间层)
tli_layer_init_struct.layer_window_leftpos = (80 + 43);//最左侧从80开始
tli_layer_init_struct.layer_window_rightpos = (80 + 400 + 43 - 1); //最右侧到80+400结束
tli_layer_init_struct.layer_window_toppos = (72 + 12);//最上侧从72开始
tli_layer_init_struct.layer_window_bottompos = (72+ 200 + 12 - 1);//最下侧到72+200结束
tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;
tli_layer_init_struct.layer_sa = 0x0;//其余部分透明显示
tli_layer_init_struct.layer_default_blue = 0xFF;
tli_layer_init_struct.layer_default_green = 0xFF;
tli_layer_init_struct.layer_default_red = 0xFF;
tli_layer_init_struct.layer_default_alpha = 0x0;
tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA;
tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA;
tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)image_gd32;//gd32图片的RGB565数组
tli_layer_init_struct.layer_frame_line_length = ((LCD_PIXEL_WIDTH * 2) + 3);
tli_layer_init_struct.layer_frame_buf_stride_offset = (LCD_PIXEL_WIDTH * 2);
tli_layer_init_struct.layer_frame_total_line_number = LCD_PIXEL_HEIGHT;
tli_layer_init(LAYER0, &tli_layer_init_struct);
tli_reload_config(TLI_REQUEST_RELOAD_EN);
lcd_font_set(&LCD_DEFAULT_FONT);
tli_dither_config(TLI_DITHER_ENABLE);
}
Here, layer0 and layer1 refer to "layer 0" and "layer 1" in the overlay layer. Both display layers are configured to be 400 wide by 200 high, and the rest is displayed transparently.
Use the keys to modify the color of the BG layer:
void change_backcolor(int n)
{
int i = n%4;
switch(i)
{
case 0:
tli_init_struct.backcolor_red = 0xFF;
tli_init_struct.backcolor_green = 0xFF;
tli_init_struct.backcolor_blue = 0xFF;
break;
case 1:
tli_init_struct.backcolor_red = 0xFF;
tli_init_struct.backcolor_green = 0x00;
tli_init_struct.backcolor_blue = 0x00;
break;
case 2:
tli_init_struct.backcolor_red = 0x00;
tli_init_struct.backcolor_green = 0xFF;
tli_init_struct.backcolor_blue = 0x00;
break;
case 3:
tli_init_struct.backcolor_red = 0x00;
tli_init_struct.backcolor_green = 0x00;
tli_init_struct.backcolor_blue = 0xFF;
break;
}
tli_init(&tli_init_struct);
}
Use the buttons to change the transparency of layer 0 and layer 1:
void lcd_layer_set(uint32_t layer)
{
if (layer == LCD_LAYER_BACKGROUND)
{
current_framebuffer = (uint32_t)image_gd32;//LCD_FRAME_BUFFER;
current_layer = LCD_LAYER_BACKGROUND;
}else
{
current_framebuffer = (uint32_t)image_eeworld;//LCD_FRAME_BUFFER + BUFFER_OFFSET;
current_layer = LCD_LAYER_FOREGROUND;
}
}
void lcd_transparency_set(uint8_t trans)
{
if (current_layer == LCD_LAYER_BACKGROUND)
{
TLI_LxSA(LAYER0) = trans;
}
else
{
TLI_LxSA(LAYER1) = trans;
}
tli_reload_config(TLI_REQUEST_RELOAD_EN);
}
//改变层0的透明度-------------
void change_layer0_transparency(int n)
{
int i = n%6;//0 1 2 3 4 5
lcd_layer_set(LCD_LAYER_BACKGROUND);
lcd_transparency_set(i*50);
}
//改变层1的透明度-------------
void change_layer1_transparency(int n)
{
int i = n%6;//0 1 2 3 4 5
lcd_layer_set(LCD_LAYER_FOREGROUND);
lcd_transparency_set(i*50);
}
5 Download Verification
Compile the program:
compiling picture.c...
linking...
Program Size: Code=4360 RO-data=334236 RW-data=80 ZI-data=1088
FromELF: creating hex file...
".\GD32F4xx-OBJ\USBH-HID.axf" - 0 Error(s), 5 Warning(s).
Build Time Elapsed: 00:00:03
It can be seen that the Code is 4360 bytes, which is more than 4K, and the RO-data is 334236 bytes , which is more than 326K. This is mainly because the RGB565 array takes up a large space.
Two 400x200 RGB565 arrays are used here, with a total size of 400x200x2x2=320000 bytes, or 320K, which occupies most of the RO-data.
For the meaning of these sizes, please refer to the introduction in " Program compilation and download " in the previous article " 【GD32450I-EVAL】+ 03 Basic usage of library functions - taking key interrupt as an example ".
Since the image takes up a large space and the downloading program takes a long time (about half a minute), you can consider how to burn the image to a certain location in the flash first, and then use the program to read it, so that you don't have to spend time burning the image data every time.
The demonstration video is as follows . By adjusting the transparency of each layer, you can clearly see the superposition relationship of each layer:
|