在学习正点原子的探索者TFTLCD(MCU屏)时对在指定区域内填充单个颜色进行(lcd_fill)修改 .

文章讲述了作者两次优化LCD屏幕填充单色的函数,原始函数只能处理左上到右下的坐标。首次修改考虑了不同对角坐标排序,第二次修改则简化条件,仅交换当sx或sy大于ex或ey时的坐标,有效处理了一条直线的填充。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

修改原因:因为原始函数只能对传进来的左上,右下的坐标进行填充。

初始条件

屏幕显示方式:竖屏

扫描方式:先从左到右,再从上到下

原始函数:


/**
 * @brief       在指定区域内填充单个颜色
 * @param       (sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex - sx + 1) * (ey - sy + 1)
 * @param       color:  要填充的颜色(32位颜色,方便兼容LTDC)
 * @retval      无
 */
void lcd_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t color)
{
    uint16_t i, j;
    uint16_t xlen = 0;
    xlen = ex - sx + 1;

    for (i = sy; i <= ey; i++)
    {
        lcd_set_cursor(sx, i);      /* 设置光标位置 */
        lcd_write_ram_prepare();    /* 开始写入GRAM */

        for (j = 0; j < xlen; j++)
        {
            LCD->LCD_RAM = color;   /* 显示颜色 */
        }
    }
}

第一次修改

/**
 * @brief       在指定区域内填充单个颜色
 * @param       (sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex - sx + 1) * (ey - sy + 1)
 * @param       color:  要填充的颜色(32位颜色,方便兼容LTDC)
 * @retval      无
 */
void lcd_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t  color)
{
    uint16_t i = 0;
    uint16_t j = 0;
    uint16_t temp = 0;
    
    /* 下面交换坐标的目的是为了让坐标变成左上,右下(排序的顺序是传进来的顺序) */
    
    /* 传入的是右下, 左上的坐标 */
    if((sx > ex) && (sy > ey))
    {
        temp = sx;
        sx = ex;
        ex = temp;
        
        temp = sy;
        sy = ey;
        ey = temp;
    }
    
    /* 传入的是左下, 右上的坐标 */
    else if(sx < ex && sy > ey)
    {
        temp = sy;
        sy = ey;
        ey = temp;
    }
    
    /* 传入的是右上, 左下的坐标 */
    else if(sx > ex && sy < ey)
    {
        temp = sx;
        sx = ex;
        ex = temp;
    }
    
    uint16_t xlen = ex - sx + 1;
    
    for(i = sy; i <= ey; i++)
    {
        lcd_set_cursor(sx, i);       /* 设置光标位置 */
        lcd_write_ram_prepare();    /* 开始写入GRAM */
        
        for(j = 0; j < xlen; j++)
        {
            LCD->LCD_RAM = color;
        }
    }
}

修改的思路:不同的两个对角画出来的是同一个矩形(确定条件:两条相邻的直线相互垂直,不相邻的平行)。但写的原始填充矩形函数是对传进来的左上,右下进行填充的,修改的函数也是在此基础上修改的。只是把传进来的不同对角坐标修改成左上,右下。

当传入的是右下, 左上的坐标时,把这两个的坐标顺序换成左上,右下就可以了。

if((sx > ex) && (sy > ey))

{

temp = sx;

sx = ex;

ex = temp;

temp = sy;

sy = ey;

ey = temp;

}

当传入的是左下, 右上的坐标时,把两个坐标的Y轴换一下就可以变成左上,右下了;

else if(sx < ex && sy > ey)

{

temp = sy;

sy = ey;

ey = temp;

}

当传入的是右上, 左下的坐标时,把两个坐标的X轴换一下就可以变成左上,右下了。

else if(sx > ex && sy < ey)

{

temp = sx;

sx = ex;

ex = temp;

}

就这样第一次修改就完成了,在这次修时并没有对是填充的区域只是一条直线时进行考虑(也没有试过能不能这样就可以填充一条直线)。因为我在想是否有一些规律能够减少代码。

这时就发现,只有sx > ex时才要交换X轴的坐标,sx < ex时是不用的,y轴也是如此。基于这个规律我做了第二次修改,且这些修改完美的解决了要填充的是一条直线的问题。

第二次修改:

/**
 * @brief       在指定区域内填充单个颜色
 * @param       (sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex - sx + 1) * (ey - sy + 1)
 * @param       color:  要填充的颜色(32位颜色,方便兼容LTDC)
 * @retval      无
 */
void lcd_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t  color)
{
    uint16_t i = 0;
    uint16_t j = 0;
    uint16_t temp = 0;
    
    /* 下面交换坐标的目的是为了让坐标变成左上,右下(排序的顺序是传进来的顺序) */
    
    if((sx > ex))
    {
        temp = sx;
        sx = ex;
        ex = temp;
    }
    
    if(sy > ey)
    {
        temp = sy;
        sy = ey;
        ey = temp;
    }
    
    uint16_t xlen = ex - sx + 1;
    
    for(i = sy; i <= ey; i++)
    {
        lcd_set_cursor(sx, i);       /* 设置光标位置 */
        lcd_write_ram_prepare();    /* 开始写入GRAM */
        
        for(j = 0; j < xlen; j++)
        {
            LCD->LCD_RAM = color;
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值