[经验分享] 【GD32E503评测】——07.LCD第二篇:绘制自定义图案

xld0932   2021-2-21 11:57 楼主

一、概述

在第一篇中我们测试了LCD的刷新速度,使用了官方提供的gd32e50x_lcd_eval.c文件已经实现的lcd_clear函数实现整屏数据填充;另外官方还提供了画水平线、画垂直线、画空心矩形和实心矩形的函数实现;本篇我们主要在调用官方提供的函数绘制图片查看显示效果之前,我们还添加了画线函数,可以实现任意起点和终点之间的连接,不局限于水平线和垂直线;还添加了画圆形图案的函数,使用中点画圆算法,实现了实心圆和空心圆的绘制;

 

二、任意起点、终点线的绘制

/*******************************************************************************
 * [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;
        }
    }
}

 

三、空心圆、实心圆的绘制

/*******************************************************************************
 * @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--;
        }
    }
}

 

四、结合官方提供的水平线、垂直线、空心矩形、实心矩形绘制DEMO图案

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

 

五、运行效果图

1.jpg

六、调试问题

在下载的官方GD32E50x_Firmware_Library_V1.1.2和GD32E50x_Demo_Suites_V1.1.1这两个文件夹中都有关于LCD有底层驱动代码,我开始使用的是GD32E50x_Firmware_Library_V1.1.2中的官方代码,在显示的时候总是读取不到LCD的Device_Code,更别说显示正常了,但使用GD32E50x_Demo_Suites_V1.1.1中的官方驱动代码,显示就是正常的,然后就对照官方例程一点点的定位,最后发现官方提供的驱动是支持不同型号TFT驱动芯片的,而我开发板上的TFT驱动芯片的操作时序配置不匹配导致了操作不成功的问题,具体修改如下所示:

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

 

七、工程源码

Project_LCD_DRAW.zip (428.28 KB)
(下载次数: 17, 2021-2-21 11:51 上传)

We are a team and we work as a team !

回复评论 (2)

绘图纯粹是算法了,考校的是算法功力,其实没啥特别考验mcu的

默认摸鱼,再摸鱼。2022、9、28
点赞  2021-2-25 22:29
引用: freebsder 发表于 2021-2-25 22:29 绘图纯粹是算法了,考校的是算法功力,其实没啥特别考验mcu的

有的哈,一个是算法的实现,还有就是MCU执行的效率和速度哈……

We are a team and we work as a team !
点赞  2021-2-26 08:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复