在LCD屏幕上渐变显示sRGB所有范围颜色, 最大可渐变16,581,375种颜色

V1.1 2024/05/12 发布于博客园

功能及原理

突发奇想将sRGB全部渐变显示出来, 于是花了好几个小时不断调试, 终于能够渐变实现.

①能够自动获取开发板的LCD驱动参数,

②能够刷新屏幕为指定颜色(清屏)

③能够在LCD屏幕上自然地渐变显示颜色, 最大可渐变16,581,375种颜色, 可帧率, 显示时间, 颜色范围

参考下面网站的色表:

在线色彩搭配工具,RGB配色器 - 在线工具 - 字客网 (fontke.com)

显示原理如下:

image

当帧率为24时(可调整), 精度x和用时y(秒)的关系:

image

函数

Get_Screeninfo( )

/**
 * @name      Get_Screeninfo
 * @brief     获取LCD屏幕硬件的宽度、高度、色深
 * @param     Manager 接收LCD屏幕信息
 * @param     lcdinfo [0]宽度 [1]高度 [2]色深
 * @return
 *      @retval    true 获取成功
 *      @retval    false 获取失败
 * @date      2024/05/11
 * @version   1.0
 * @note
 * 使用示范
 * LcdInfo_t lcdinfo;
 * lcdinfo.lcd_fd_Path = "/dev/fb0";
 * Get_Screeninfo(&lcdinfo);
 */
bool Get_Screeninfo(LcdInfo_t *Manager)
{

    // 打开LCD 设备驱动 获取文件描述符 以读写权限 注意返回的是数值!
    int lcd_fd = open(Manager->lcd_fd_Path, O_RDWR);
    if (-1 == lcd_fd)
    {
        perror("打开LCD驱动文件失败");
        return false;
    }

    // 利用文件控制函数获取获取lcd参数信息, 获取可变参数 "cat /usr/include/linux/fb.h"
    // 定义一个结构体变量接收返回的信息
    struct fb_var_screeninfo vinfo;

    // 获取信息, 将信息写入上述的结构体变量中
    ioctl(lcd_fd, FBIOGET_VSCREENINFO, &vinfo);

    // 写入LCD的宽度,高度,色深
    Manager->LcdWidth = vinfo.xres;
    Manager->LcdHeight = vinfo.yres;
    Manager->LcdBpp = vinfo.bits_per_pixel;
    // 关闭lcd驱动文件
    close(lcd_fd);
    return true;
}

Clear_Screen( )

/**
 * @name      Clear_Screen
 * @brief     清屏函数, 刷新屏幕为指定颜色
 * @param     Manager 要刷新的屏幕信息结构体
 * @param     color 要刷新的颜色 0x00FFFFFF ARGB
 * @return
 *      @retval    true 获取成功
 *      @retval    false 获取失败
 * @date      2024/05/11
 * @version   1.0
 * @note
 * 使用示范 Clear_Screen(&lcdinfo, 0x00FF0000); 刷新为红色
 */
bool Clear_Screen(LcdInfo_t *Manager, int color)
{
    // 打开LCD设备驱动文件 读写方式
    int lcd_fd = open(Manager->lcd_fd_Path, O_RDWR);
    if (-1 == lcd_fd)
    {
        printf("打开lcd设备驱动文件失败!\n");
        return false;
    }

    // 对LCD进行内存映射  mmap函数 接收返回值
    int *lcd_mp = (int *)mmap(
        NULL,                                                           // 映射后的内存地址由内核自动分配
        Manager->LcdWidth * Manager->LcdHeight * (Manager->LcdBpp / 8), // 屏幕对应的字节数
        PROT_READ | PROT_WRITE,                                         // 可读可写
        MAP_SHARED,                                                     // 该映射的内存空间可共享
        lcd_fd,                                                         // 文件描述符
        0);                                                             // 偏移量0
    // 错误处理
    if (MAP_FAILED == lcd_mp)
    {
        printf("lcd设备驱动文件内存映射失败!\n");
        return false;
    }

    // 把颜色分量写入到申请的映射内存空间中,通过地址偏移实现访问
    for (int i = 0; i < Manager->LcdWidth * Manager->LcdHeight; ++i)
    {
        lcd_mp[i] = color;
    }

    // 关闭LCD并解除内存映射
    munmap(lcd_mp, Manager->LcdWidth * Manager->LcdHeight * (Manager->LcdBpp / 8));
    // 关闭LCD设备驱动文件
    close(lcd_fd);

    return true;
}

Displays_GradientColorEffect( )

/**
 * @name      Displays_GradientColorEffect
 * @brief     在LCD屏幕上渐变显示sRGB所有范围颜色, 最大可渐变16,581,375种颜色
 * @param     lcdinfo LCD屏幕信息;
 * @param     FrameRatedx 显示帧率24-60;
 * @param     SetShowTime 你要显示的时间长度(秒)
 * @param     step 颜色精度(1-255) 越低表示显示种数越多 最大可显示255^3种 (51表示216种 24表示1331种)
 * @return
 *      @retval    true 提前达到预定显示时间
 * @date      2024/05/12
 * @version   1.0
 * @note
 *      使用示范
 *       Displays_GradientColorEffect(&lcdinfo, FRAMERATED, 120, 24);
 *      显示一轮所用时间为y=((255/step +1)^3)/FrameRatedx 秒
 *      请注意一轮的显示时间长短
 */
bool Displays_GradientColorEffect(LcdInfo_t *lcdinfo, int FrameRatedx, unsigned long long SetShowTime, int step)
{
    int SleepTime = 1000000 / FrameRatedx;                                        // 将帧率转换为微秒时间 帧间隔需要多少时间
    unsigned long long SetFrameRatedxCount = (SetShowTime * 1000000) / SleepTime; // 用户要求一共刷新多少帧
    // 显示精度 步进值 默认 51(step) 最大255 显示颜色数量为 ((255/step)+1)^3

    // 开始的颜色分量
    unsigned int startColor = 0;
    // 当前颜色分量
    unsigned int CurrentColor = 0;
    // 计算最大显示颜色数量
    unsigned long ShowCount = ((255 / step) + 1) * ((255 / step) + 1) * ((255 / step) + 1);
    // 计算一轮显示需要的显示时间 秒
    int ShowTime = ShowCount / FrameRatedx;

    // 解算得到颜色分量组成 ARGB
    // 控制红色见渐变
    int r = (startColor >> 16) & 0xFF;
    bool flagR = true; // true 表示颜色由深到浅色 false表示颜色由浅色到深色

    // 控制绿色见渐变
    int g = (startColor >> 8) & 0xFF;
    bool flagG = true; // true 表示颜色由深到浅色 false表示颜色由浅色到深色

    // 控制蓝色见渐变
    int b = startColor & 0xFF;
    bool flagB = true; // true 表示颜色由深到浅色 false表示颜色由浅色到深色
    printf("可以显示: %d 块色块,\n", (255 / step) + 1);
    printf("可以显示: %d 条色带\n", (((255 / step) + 1) * ((255 / step) + 1)));
    printf("可以显示: %lu 种颜色,\n", ShowCount);

    printf("每个色块内有 %d 条色带,\n", (255 / step) + 1);
    printf("每条色带内由 %d 种颜色组成,\n", (255 / step) + 1);
    printf("每个色块有 %d 种颜色,\n", ((255 / step) + 1)) * ((255 / step) + 1);

    printf("一次循环需要 %d秒 即 %d 分钟才能显示完成 \n", ShowTime, ShowTime / 60);

    while (1)
    {

        if (flagG)
        {
            for (g = 0x00; g <= 0xFF; g += step)
            {
                //               printf("\n");
                //               printf("新色块开始(%#x)\n", CurrentColor);

                if (flagB)
                {
                    for (b = 0x00; b <= 0xFF; b += step)
                    {
                        //                       printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0xFF;
                    // ????FF
                    flagB = !flagB;
                }
                else
                {
                    // ????FF
                    for (b = 0xFF; b >= 0x00; b -= step) // 同色段渐变
                    {
                        //                        printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0x00;
                    // ????00
                    flagB = !flagB;
                }
            }
            g = 0xFF;
            // ??FF??
            flagG = !flagG;
        }
        else
        {
            // ??FF??
            for (g = 0xFF; g >= 0x00; g -= step) // 同色段渐变
            {
                //               printf("\n");
                //             printf("新色块开始(%#x)\n", CurrentColor);
                if (flagB)
                {
                    for (b = 0x00; b <= 0xFF; b += step)
                    {
                        //          printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0xFF;
                    // ????FF
                    flagB = !flagB;
                }
                else
                {
                    // ????FF
                    for (b = 0xFF; b >= 0x00; b -= step) // 同色段渐变
                    {
                        //                  printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0x00;
                    // ????00
                    flagB = !flagB;
                }
            }
            g = 0x00;
            // ??00??
            flagG = !flagG;
        }
    }
}

测试

FileIOLibrary.c

/**
 * @file name : FileIOLibrary.c
 * @brief     : 实现文件IO相关接口函数的封装
 * @author    : RISE_AND_GRIND@163.com
 * @date      : 2024/05/11
 * @version   : 1.0
 * @note      : 模块化实现
 * CopyRight (c)  2023-2024   RISE_AND_GRIND@163.com   All Right Reseverd
 */
#include "FileIOLibrary.h"

/**
 * @name      Get_Screeninfo
 * @brief     获取LCD屏幕硬件的宽度、高度、色深
 * @param     Manager 接收LCD屏幕信息
 * @param     lcdinfo [0]宽度 [1]高度 [2]色深
 * @return
 *      @retval    true 获取成功
 *      @retval    false 获取失败
 * @date      2024/05/11
 * @version   1.0
 * @note
 * 使用示范
 * LcdInfo_t lcdinfo;
 * lcdinfo.lcd_fd_Path = "/dev/fb0";
 * Get_Screeninfo(&lcdinfo);
 */
bool Get_Screeninfo(LcdInfo_t *Manager)
{

    // 打开LCD 设备驱动 获取文件描述符 以读写权限 注意返回的是数值!
    int lcd_fd = open(Manager->lcd_fd_Path, O_RDWR);
    if (-1 == lcd_fd)
    {
        perror("打开LCD驱动文件失败");
        return false;
    }

    // 利用文件控制函数获取获取lcd参数信息, 获取可变参数 "cat /usr/include/linux/fb.h"
    // 定义一个结构体变量接收返回的信息
    struct fb_var_screeninfo vinfo;

    // 获取信息, 将信息写入上述的结构体变量中
    ioctl(lcd_fd, FBIOGET_VSCREENINFO, &vinfo);

    // 写入LCD的宽度,高度,色深
    Manager->LcdWidth = vinfo.xres;
    Manager->LcdHeight = vinfo.yres;
    Manager->LcdBpp = vinfo.bits_per_pixel;
    // 关闭lcd驱动文件
    close(lcd_fd);
    return true;
}

/**
 * @name      Clear_Screen
 * @brief     清屏函数, 刷新屏幕为指定颜色
 * @param     Manager 要刷新的屏幕信息结构体
 * @param     color 要刷新的颜色 0x00FFFFFF ARGB
 * @return
 *      @retval    true 获取成功
 *      @retval    false 获取失败
 * @date      2024/05/11
 * @version   1.0
 * @note
 * 使用示范 Clear_Screen(&lcdinfo, 0x00FF0000); 刷新为红色
 */
bool Clear_Screen(LcdInfo_t *Manager, int color)
{
    // 打开LCD设备驱动文件 读写方式
    int lcd_fd = open(Manager->lcd_fd_Path, O_RDWR);
    if (-1 == lcd_fd)
    {
        printf("打开lcd设备驱动文件失败!\n");
        return false;
    }

    // 对LCD进行内存映射  mmap函数 接收返回值
    int *lcd_mp = (int *)mmap(
        NULL,                                                           // 映射后的内存地址由内核自动分配
        Manager->LcdWidth * Manager->LcdHeight * (Manager->LcdBpp / 8), // 屏幕对应的字节数
        PROT_READ | PROT_WRITE,                                         // 可读可写
        MAP_SHARED,                                                     // 该映射的内存空间可共享
        lcd_fd,                                                         // 文件描述符
        0);                                                             // 偏移量0
    // 错误处理
    if (MAP_FAILED == lcd_mp)
    {
        printf("lcd设备驱动文件内存映射失败!\n");
        return false;
    }

    // 把颜色分量写入到申请的映射内存空间中,通过地址偏移实现访问
    for (int i = 0; i < Manager->LcdWidth * Manager->LcdHeight; ++i)
    {
        lcd_mp[i] = color;
    }

    // 关闭LCD并解除内存映射
    munmap(lcd_mp, Manager->LcdWidth * Manager->LcdHeight * (Manager->LcdBpp / 8));
    // 关闭LCD设备驱动文件
    close(lcd_fd);

    return true;
}

/**
 * @name      Displays_GradientColorEffect
 * @brief     在LCD屏幕上渐变显示颜色, 最大可渐变16,581,375种颜色
 * @param     lcdinfo LCD屏幕信息;
 * @param     FrameRatedx 显示帧率24-60;
 * @param     SetShowTime 你要显示的时间长度(秒)
 * @param     step 颜色精度(1-255) 越低表示显示种数越多 最大可显示255^3种 (51表示216种 24表示1331种)
 * @return
 *      @retval    true 提前达到预定显示时间
 * @date      2024/05/12
 * @version   1.0
 * @note
 *      使用示范
 *       Displays_GradientColorEffect(&lcdinfo, FRAMERATED, 120, 24);
 *      显示一轮所用时间为y=((255/step +1)^3)/FrameRatedx 秒
 *      请注意一轮的显示时间长短
 */
bool Displays_GradientColorEffect(LcdInfo_t *lcdinfo, int FrameRatedx, unsigned long long SetShowTime, int step)
{
    int SleepTime = 1000000 / FrameRatedx;                                        // 将帧率转换为微秒时间 帧间隔需要多少时间
    unsigned long long SetFrameRatedxCount = (SetShowTime * 1000000) / SleepTime; // 用户要求一共刷新多少帧
    // 显示精度 步进值 默认 51(step) 最大255 显示颜色数量为 ((255/step)+1)^3

    // 开始的颜色分量
    unsigned int startColor = 0;
    // 当前颜色分量
    unsigned int CurrentColor = 0;
    // 计算最大显示颜色数量
    unsigned long ShowCount = ((255 / step) + 1) * ((255 / step) + 1) * ((255 / step) + 1);
    // 计算一轮显示需要的显示时间 秒
    int ShowTime = ShowCount / FrameRatedx;

    // 解算得到颜色分量组成 ARGB
    // 控制红色见渐变
    int r = (startColor >> 16) & 0xFF;
    bool flagR = true; // true 表示颜色由深到浅色 false表示颜色由浅色到深色

    // 控制绿色见渐变
    int g = (startColor >> 8) & 0xFF;
    bool flagG = true; // true 表示颜色由深到浅色 false表示颜色由浅色到深色

    // 控制蓝色见渐变
    int b = startColor & 0xFF;
    bool flagB = true; // true 表示颜色由深到浅色 false表示颜色由浅色到深色
    printf("可以显示: %d 块色块,\n", (255 / step) + 1);
    printf("可以显示: %d 条色带\n", (((255 / step) + 1) * ((255 / step) + 1)));
    printf("可以显示: %lu 种颜色,\n", ShowCount);

    printf("每个色块内有 %d 条色带,\n", (255 / step) + 1);
    printf("每条色带内由 %d 种颜色组成,\n", (255 / step) + 1);
    printf("每个色块有 %d 种颜色,\n", ((255 / step) + 1)) * ((255 / step) + 1);

    printf("一次循环需要 %d秒 即 %d 分钟才能显示完成 \n", ShowTime, ShowTime / 60);

    while (1)
    {

        if (flagG)
        {
            for (g = 0x00; g <= 0xFF; g += step)
            {
                //               printf("\n");
                //               printf("新色块开始(%#x)\n", CurrentColor);

                if (flagB)
                {
                    for (b = 0x00; b <= 0xFF; b += step)
                    {
                        //                       printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0xFF;
                    // ????FF
                    flagB = !flagB;
                }
                else
                {
                    // ????FF
                    for (b = 0xFF; b >= 0x00; b -= step) // 同色段渐变
                    {
                        //                        printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0x00;
                    // ????00
                    flagB = !flagB;
                }
            }
            g = 0xFF;
            // ??FF??
            flagG = !flagG;
        }
        else
        {
            // ??FF??
            for (g = 0xFF; g >= 0x00; g -= step) // 同色段渐变
            {
                //               printf("\n");
                //             printf("新色块开始(%#x)\n", CurrentColor);
                if (flagB)
                {
                    for (b = 0x00; b <= 0xFF; b += step)
                    {
                        //          printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0xFF;
                    // ????FF
                    flagB = !flagB;
                }
                else
                {
                    // ????FF
                    for (b = 0xFF; b >= 0x00; b -= step) // 同色段渐变
                    {
                        //                  printf("新色带:(%#x)\n", CurrentColor);
                        if (flagR)
                        {
                            // 00????
                            for (r = 0x00; r <= 0xFF; r += step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0xFF;
                            // FF????
                            flagR = !flagR;
                        }
                        else
                        {
                            // FF????
                            for (r = 0xFF; r >= 0x00; r -= step) // 同色段渐变
                            {
                                //               A              r           g        b
                                CurrentColor = (0x00 << 24) | (r << 16) | (g << 8) | b; // 生成颜色
                                Clear_Screen(lcdinfo, CurrentColor);
                                usleep(SleepTime);
                                // 达到要求时间, 退出程序
                                SetFrameRatedxCount--;
                                if (SetFrameRatedxCount == 0)
                                {
                                    return true;
                                }
                            }
                            r = 0x00;
                            // 00????
                            flagR = !flagR;
                        }
                    }
                    b = 0x00;
                    // ????00
                    flagB = !flagB;
                }
            }
            g = 0x00;
            // ??00??
            flagG = !flagG;
        }
    }
}

FileIOLibrary.h

#ifndef __FILEIOLIBRARY_H
#define __FILEIOLIBRARY_H

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <unistd.h>

// LCD设备的相关信息储存
typedef struct
{
    char *lcd_fd_Path;      // LCD设备驱动文件地址 "/dev/fb0"
    unsigned int LcdWidth;  // LCD的宽度
    unsigned int LcdHeight; // LCD的高度
    unsigned int LcdBpp;    // LCD的色深
} LcdInfo_t;
/**
 * @name      Get_Screeninfo
 * @brief     获取LCD屏幕硬件的宽度、高度、色深
 * @param     Manager 接收LCD屏幕驱动文件
 * @param     lcdinfo [0]宽度 [1]高度 [2]色深
 * @return
 *      @retval    true 获取成功
 *      @retval    false 获取失败
 * @date      2024/05/11
 * @version   1.0
 * @note
 * 使用示范
 * LcdInfo_t lcdinfo;
 * lcdinfo.lcd_fd_Path = "/dev/fb0";
 * Get_Screeninfo(&lcdinfo);
 */
bool Get_Screeninfo(LcdInfo_t *Manager);

/**
 * @name      Clear_Screen
 * @brief     清屏函数, 刷新屏幕为指定颜色
 * @param     Manager 要刷新的屏幕信息结构体
 * @param     color 要刷新的颜色 0x00FFFFFF ARGB
 * @return
 *      @retval    true 获取成功
 *      @retval    false 获取失败
 * @date      2024/05/11
 * @version   1.0
 * @note
 * 使用示范 Clear_Screen(&lcdinfo, 0x00FF0000); 刷新为红色
 */
bool Clear_Screen(LcdInfo_t *Manager, int color);

/**
 * @name      Displays_GradientColorEffect
 * @brief     在LCD屏幕上渐变显示颜色, 最大可渐变16,581,375种颜色
 * @param     lcdinfo LCD屏幕信息;
 * @param     FrameRatedx 显示帧率24-60;
 * @param     SetShowTime 你要显示的时间长度(秒)
 * @param     step 颜色精度(1-255) 越低表示显示种数越多 最大可显示255^3种 (51表示216种 24表示1331种)
 * @return
 *      @retval    true 提前达到预定显示时间
 * @date      2024/05/12
 * @version   1.0
 * @note
 *      使用示范
 *       Displays_GradientColorEffect(&lcdinfo, FRAMERATED, 120, 24);
 *      显示一轮所用时间为y=((255/step +1)^3)/FrameRatedx 秒
 *      请注意一轮的显示时间长短
 */
bool Displays_GradientColorEffect(LcdInfo_t *lcdinfo, int FrameRatedx, unsigned long long SetShowTime, int step);


#endif

testing.c

#include "FileIOLibrary.h"

#define FRAMERATED 24 // 帧率
int main(int argc, char const *argv[])
{
    LcdInfo_t lcdinfo;
    lcdinfo.lcd_fd_Path = "/dev/fb0";
    Get_Screeninfo(&lcdinfo);
    printf("高度 %d\n", lcdinfo.LcdHeight);
    printf("宽度 %d\n", lcdinfo.LcdWidth);
    printf("色深 %d\n", lcdinfo.LcdBpp);
    Displays_GradientColorEffect(&lcdinfo, FRAMERATED, 120, 51);
}

结果

[root@GEC6818 /yuyiworkspace]#./cheak
高度 480
宽度 800
色深 32
可以显示: 6 块色块,
可以显示: 36 条色带
可以显示: 216 种颜色,
每个色块内有 6 条色带,
每条色带内由 6 种颜色组成,
每个色块有 6 种颜色,
一次循环需要 9秒 即 0 分钟才能显示完成

[root@GEC6818 /yuyiworkspace]#./0157
高度 480
宽度 800
色深 32
可以显示: 11 块色块,
可以显示: 121 条色带
可以显示: 1331 种颜色,
每个色块内有 11 条色带,
每条色带内由 11 种颜色组成,
每个色块有 11 种颜色,
一次循环需要 55秒 即 0 分钟才能显示完成

[root@GEC6818 /yuyiworkspace]#./0157
高度 480
宽度 800
色深 32
可以显示: 6 块色块,
可以显示: 36 条色带
可以显示: 216 种颜色,
每个色块内有 6 条色带,
每条色带内由 6 种颜色组成,
每个色块有 6 种颜色,
一次循环需要 9秒 即 0 分钟才能显示完成

新色块开始(0)
新色带:(0)
新色带:(0xff0000)
新色带:(0x33)
新色带:(0xff0066)
新色带:(0x99)
新色带:(0xff00cc)

新色块开始(0xff)
新色带:(0xff)
新色带:(0xff33ff)
新色带:(0x33cc)
新色带:(0xff3399)
新色带:(0x3366)
新色带:(0xff3333)

新色块开始(0x3300)
新色带:(0x3300)
新色带:(0xff6600)
新色带:(0x6633)
新色带:(0xff6666)
新色带:(0x6699)
新色带:(0xff66cc)

新色块开始(0x66ff)
新色带:(0x66ff)
新色带:(0xff99ff)
新色带:(0x99cc)
新色带:(0xff9999)
新色带:(0x9966)
新色带:(0xff9933)

新色块开始(0x9900)
新色带:(0x9900)
新色带:(0xffcc00)
新色带:(0xcc33)
新色带:(0xffcc66)
新色带:(0xcc99)
新色带:(0xffcccc)

新色块开始(0xccff)
新色带:(0xccff)
新色带:(0xffffff)
新色带:(0xffcc)
新色带:(0xffff99)
新色带:(0xff66)
新色带:(0xffff33)

新色块开始(0xff00)
新色带:(0xff00)
新色带:(0xffff00)
新色带:(0xff33)
新色带:(0xffff66)
新色带:(0xff99)
新色带:(0xffffcc)

新色块开始(0xffff)
新色带:(0xffff)
新色带:(0xffccff)
新色带:(0xcccc)
新色带:(0xffcc99)
新色带:(0xcc66)
新色带:(0xffcc33)

新色块开始(0xcc00)
新色带:(0xcc00)
新色带:(0xff9900)
新色带:(0x9933)
新色带:(0xff9966)
新色带:(0x9999)
新色带:(0xff99cc)

新色块开始(0x99ff)
新色带:(0x99ff)
新色带:(0xff66ff)
新色带:(0x66cc)
新色带:(0xff6699)
新色带:(0x6666)
新色带:(0xff6633)

新色块开始(0x6600)
新色带:(0x6600)
新色带:(0xff3300)
新色带:(0x3333)
新色带:(0xff3366)
新色带:(0x3399)
新色带:(0xff33cc)

新色块开始(0x33ff)
新色带:(0x33ff)
新色带:(0xff00ff)
新色带:(0xcc)
新色带:(0xff0099)
新色带:(0x66)
新色带:(0xff0033)

新色块开始(0)
新色带:(0)
新色带:(0xff0000)
新色带:(0x33)
新色带:(0xff0066)
新色带:(0x99)
新色带:(0xff00cc)

新色块开始(0xff)
新色带:(0xff)
新色带:(0xff33ff)
新色带:(0x33cc)
新色带:(0xff3399)
新色带:(0x3366)
新色带:(0xff3333)

新色块开始(0x3300)
新色带:(0x3300)
新色带:(0xff6600)
新色带:(0x6633)
新色带:(0xff6666)
新色带:(0x6699)
新色带:(0xff66cc)

新色块开始(0x66ff)
新色带:(0x66ff)
新色带:(0xff99ff)
新色带:(0x99cc)
新色带:(0xff9999)
新色带:(0x9966)
新色带:(0xff9933)

新色块开始(0x9900)
新色带:(0x9900)
新色带:(0xffcc00)
新色带:(0xcc33)
新色带:(0xffcc66)
新色带:(0xcc99)
新色带:(0xffcccc)

新色块开始(0xccff)
新色带:(0xccff)
新色带:(0xffffff)
新色带:(0xffcc)
新色带:(0xffff99)
新色带:(0xff66)
新色带:(0xffff33)

新色块开始(0xff00)
新色带:(0xff00)
新色带:(0xffff00)
新色带:(0xff33)
新色带:(0xffff66)
新色带:(0xff99)
新色带:(0xffffcc)

新色块开始(0xffff)
新色带:(0xffff)
新色带:(0xffccff)
新色带:(0xcccc)
新色带:(0xffcc99)
新色带:(0xcc66)
新色带:(0xffcc33)

新色块开始(0xcc00)
新色带:(0xcc00)
新色带:(0xff9900)
新色带:(0x9933)
新色带:(0xff9966)
新色带:(0x9999)
新色带:(0xff99cc)

新色块开始(0x99ff)
新色带:(0x99ff)
新色带:(0xff66ff)
新色带:(0x66cc)
新色带:(0xff6699)
新色带:(0x6666)
新色带:(0xff6633)

新色块开始(0x6600)
新色带:(0x6600)
新色带:(0xff3300)
新色带:(0x3333)
新色带:(0xff3366)
新色带:(0x3399)
新色带:(0xff33cc)

新色块开始(0x33ff)
新色带:(0x33ff)
新色带:(0xff00ff)
新色带:(0xcc)
新色带:(0xff0099)
新色带:(0x66)
新色带:(0xff0033)

posted @ 2024-05-12 04:43  舟清颺  阅读(39)  评论(0编辑  收藏  举报