4380 views|2 replies

205

Posts

0

Resources
The OP
 

[GD32E503 Review]——07.LCD Part 2: Drawing Custom Patterns [Copy link]

1. Overview

In the first article, we tested the refresh speed of the LCD and used the lcd_clear function implemented in the official gd32e50x_lcd_eval.c file to fill the entire screen with data. In addition, the official also provided functions for drawing horizontal lines, vertical lines, hollow rectangles, and solid rectangles. In this article, before calling the official function to draw pictures and check the display effect, we also added a line drawing function, which can connect any starting point and end point, not limited to horizontal and vertical lines. We also added a function for drawing circular patterns, using the midpoint circle drawing algorithm to achieve the drawing of solid and hollow circles.

2. Drawing of arbitrary starting and ending lines

/*******************************************************************************
 * [url=home.php?mod=space&uid=159083]@brief[/url] * @param       
 * @retval      
 * [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void LCD_DrawLine(uint16_t StartX, uint16_t StartY, uint16_t EndX, uint16_t EndY, uint16_t Color)
{
    uint16_t CurrentX = StartX; 
    uint16_t CurrentY = StartY; 

    int16_t  DeltaX = EndX - StartX;
    int16_t  DeltaY = EndY - StartY;

    int16_t  IncreaseX = 0, OffsetX = 0;
    int16_t  IncreaseY = 0, OffsetY = 0;

    uint16_t Distance = 0;

    if(DeltaX > 0)
    {
        IncreaseX = 1;
    }
    else if(DeltaX == 0)
    {
        IncreaseX = 0;
    }
    else
    {
        IncreaseX  =  -1;
        DeltaX = -DeltaX;
    }

    if(DeltaY > 0)
    {
        IncreaseY = 1;
    }
    else if(DeltaY == 0)
    {
        IncreaseY = 0;
    }
    else
    {
        IncreaseY  =  -1;
        DeltaY = -DeltaY;
    }

    if(DeltaX > DeltaY) Distance = DeltaX;
    else                Distance = DeltaY;

    for(uint16_t i = 0; i <= Distance + 1; i++)
    {
        lcd_point_set(CurrentX, CurrentY, Color);

        OffsetX += DeltaX;
        OffsetY += DeltaY;

        if(OffsetX > Distance)
        {
            OffsetX  -= Distance;
            CurrentX += IncreaseX;
        }

        if(OffsetY > Distance)
        {
            OffsetY  -= Distance;
            CurrentY += IncreaseY;
        }
    }
}

3. Drawing of hollow circle and solid circle

/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void LCD_DrawCircle(uint16_t CenterX, uint16_t CenterY, uint16_t Radius, uint16_t Color, uint8_t Filled)
{
    int16_t CurrentX = 0, CurrentY = Radius;
    int16_t Distance = 3 - (Radius << 0x01);

    while(CurrentX <= CurrentY)
    {
        if(Filled)
        {
            for(int16_t i = CurrentX; i <= CurrentY; i++)
            {
                lcd_point_set(CenterX + CurrentX, CenterY + i,        Color);
                lcd_point_set(CenterX - CurrentX, CenterY + i,        Color);
                lcd_point_set(CenterX - i,        CenterY + CurrentX, Color);
                lcd_point_set(CenterX - i,        CenterY - CurrentX, Color);
                lcd_point_set(CenterX - CurrentX, CenterY - i,        Color);
                lcd_point_set(CenterX + CurrentX, CenterY - i,        Color);
                lcd_point_set(CenterX + i,        CenterY - CurrentX, Color);
                lcd_point_set(CenterX + i,        CenterY + CurrentX, Color);
            }
        }
        else
        {
            lcd_point_set(CenterX + CurrentX, CenterY + CurrentY, Color);
            lcd_point_set(CenterX - CurrentX, CenterY + CurrentY, Color);
            lcd_point_set(CenterX - CurrentY, CenterY + CurrentX, Color);
            lcd_point_set(CenterX - CurrentY, CenterY - CurrentX, Color);
            lcd_point_set(CenterX - CurrentX, CenterY - CurrentY, Color);
            lcd_point_set(CenterX + CurrentX, CenterY - CurrentY, Color);
            lcd_point_set(CenterX + CurrentY, CenterY - CurrentX, Color);
            lcd_point_set(CenterX + CurrentY, CenterY + CurrentX, Color);
        }

        CurrentX++;

        if(Distance < 0)
        {
            Distance += (4 * CurrentX + 6);
        }
        else
        {
            Distance += (10 + 4 * (CurrentX - CurrentY));
            CurrentY--;
        }
    }
}

4. Draw the DEMO pattern by combining the horizontal lines, vertical lines, hollow rectangles and solid rectangles provided by the official website

/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void LCD_Demo(void)
{
    LCD_DrawLine(50, 50, 50,  100, LCD_COLOR_RED);
    LCD_DrawLine(50, 50, 100, 50,  LCD_COLOR_RED);
    LCD_DrawLine(50, 50, 100, 100, LCD_COLOR_RED);

    lcd_rectangle_draw(120, 120, 170, 170, LCD_COLOR_YELLOW);

    LCD_DrawCircle(50,  200, 40, LCD_COLOR_BLACK, 0);

    LCD_DrawCircle(50,  200, 20, LCD_COLOR_BLACK, 1);

    lcd_rectangle_fill(140, 240, 160, 260, LCD_COLOR_YELLOW);

    LCD_DrawCircle(150, 250, 40, LCD_COLOR_WHITE, 0);
}

5. Operation effect diagram

6. Debugging issues

In the two folders of the downloaded official GD32E50x_Firmware_Library_V1.1.2 and GD32E50x_Demo_Suites_V1.1.1, there are low-level driver codes for LCD. I started using the official code in GD32E50x_Firmware_Library_V1.1.2. When displaying, I could not read the LCD Device_Code, let alone display it normally. However, using the official driver code in GD32E50x_Demo_Suites_V1.1.1, the display was normal. Then I compared it with the official routines little by little, and finally found that the official driver supports different models of TFT driver chips, and the operation timing configuration of the TFT driver chip on my development board does not match, which leads to the problem of unsuccessful operation. The specific modifications are as follows:

/*!
    \brief      lcd peripheral initialize
    \param[in]  none 
    \param[out] none
    \retval     none
*/
void exmc_lcd_init(void)
{
    exmc_norsram_parameter_struct lcd_init_struct;
    exmc_norsram_timing_parameter_struct lcd_timing_init_struct;

    /* 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);

    /* 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_50MHZ, 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_50MHZ, 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_A23) */ 
    gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
    
    /* configure PD4(NOE) and PD5(NWE) */
    gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5);

    /* configure PG9(EXMC NE1) */
    gpio_init(GPIOG, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);

    lcd_timing_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A;
    lcd_timing_init_struct.syn_data_latency = EXMC_DATALAT_2_CLK;
    lcd_timing_init_struct.syn_clk_division = EXMC_SYN_CLOCK_RATIO_DISABLE;
    lcd_timing_init_struct.bus_latency = 2;
#if 0
    lcd_timing_init_struct.asyn_data_setuptime = 10;
    lcd_timing_init_struct.asyn_address_holdtime = 2;
    lcd_timing_init_struct.asyn_address_setuptime = 5;
#else
    lcd_timing_init_struct.asyn_data_setuptime = 18;
    lcd_timing_init_struct.asyn_address_holdtime = 3;
    lcd_timing_init_struct.asyn_address_setuptime = 8;
#endif

    lcd_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION0;
    lcd_init_struct.write_mode = EXMC_ASYN_WRITE;
    lcd_init_struct.extended_mode = DISABLE;
    lcd_init_struct.asyn_wait = DISABLE;
    lcd_init_struct.nwait_signal = DISABLE;
    lcd_init_struct.memory_write = ENABLE;
    lcd_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
    lcd_init_struct.wrap_burst_mode = DISABLE;
    lcd_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
    lcd_init_struct.burst_mode = DISABLE;
    lcd_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
    lcd_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;
    lcd_init_struct.address_data_mux = DISABLE;
    lcd_init_struct.read_write_timing = &lcd_timing_init_struct;
    lcd_init_struct.write_timing = &lcd_timing_init_struct;

    exmc_norsram_init(&lcd_init_struct);

    exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION1);
}

7. Project source code

Project_LCD_DRAW.zip (428.28 KB, downloads: 17)

This post is from GD32 MCU

Latest reply

Drawing is purely an algorithm, which tests the algorithmic skills. In fact, there is nothing special about the MCU.   Details Published on 2021-2-25 22:29
Personal signatureWe are a team and we work as a team !
 

7422

Posts

2

Resources
2
 

Drawing is purely an algorithm, which tests the algorithmic skills. In fact, there is nothing special about the MCU.

This post is from GD32 MCU

Comments

Yes, one is the implementation of the algorithm, and the other is the efficiency and speed of MCU execution...  Details Published on 2021-2-26 08:24
 
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 

205

Posts

0

Resources
3
 
freebsder posted on 2021-2-25 22:29 Drawing is purely an algorithm. It tests the algorithmic skills. In fact, there is nothing special about the MCU

Yes, one is the implementation of the algorithm, and the other is the efficiency and speed of MCU execution...

This post is from GD32 MCU
 
Personal signatureWe are a team and we work as a team !
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list