当前位置: 首页 > news >正文

知识点1-lcd点亮->frame buffer、字库

一、frame buff 帧缓冲

1、概念:

        帧缓存(fps一秒多少帧)

        是一种图形硬件抽象层,它将显示设备的显存映射到系统内存中,使得应用程序可以直接通过读写内存来控制屏幕上的像素显示。这段代码实现了打开帧缓冲设备、获取设备的相关参数(如分辨率、位深度等),并将显存映射到用户空间的功能。

2、相关概念:

  • 分辨率:宽高(广泛理解)
    • 例如:imx6ull 板子的分辨率为:800*480(4.3寸)
  • 色深:颜色空间、颜色深度、位深度(位越高,颜色越细腻)
    • 类型:RGB、yuv、HSV
      • 例如:imx6ull 板子的色深:RGB,888,24bit(位越高,颜色越细腻)
      • imx6ull 板子的触屏接I2C
  • 一秒三十帧画面
    • 大小34M =800*480*3(RGB)*30(一秒30帧)
    • 太大,所以采用并行传输(距离不能太远、速度越快越受到干扰)

3、lcd绘制:

        实际屏幕对应一块显存,内存映射过来是一个长条,应用不能直接操作硬件,linux,驱动,合法手段内存映射mmap;如图所示

4、代码实现

void *pmem;                //存储显存映射到用户后的起始地址
struct fb_var_screeninfo vinf;        //结构体:存储:设备分辨率、色深等..

//打开字符串为devname的帧缓冲设备

int init_fb(char *devname)
{
//1. 以读写模式打开帧缓冲设备文件
int fd = open(devname, O_RDWR);    
if (-1 == fd)
{
perror("fail open fb");
return -1;
}

//2、获取显示设备相关参数 分辨率 位深度
int ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinf);
if (-1 ==ret)
{
perror("fail ioctl");
return -1;
}

printf("xres = %d, yres = %d\n", vinf.xres, vinf.yres);
printf("xres_virtual = %d, yres_virtual = %d\n", vinf.xres_virtual, vinf.yres_virtual);
printf("bits_per_pixel : %d\n", vinf.bits_per_pixel);

    size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;


//3, 建立显存和用户空间的映射关系(将显存映射到用户空间)
pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if ((void *)-1 == pmem)
{
perror("fail mmap");
return -1;
}

return fd;
}

表格总结

步骤函数调用作用i.MX6ULL 特殊考量
1open("/dev/fb0", ...)打开帧缓冲设备文件需确认设备节点为 /dev/fb0 或 /dev/fb1
2ioctl(FBIOGET_VSCREENINFO)获取屏幕参数(分辨率/色深)需匹配芯片的显示控制器(如 DCSS/EPDC)
3mmap()将显存映射到用户空间物理地址需对齐 MX6ULL 的 MMU 配置
4返回文件描述符供后续绘图操作使用需保持打开状态直到程序结束

5、显示点

//显示点

//传入点的位置,以及颜色
void draw_point(int x, int y, unsigned int col)
{

    //若超出边界则直接返回
if (x >= vinf.xres || y >= vinf.yres)
{
return ;
}

     //若色深为RGB 888 执行以下画点
if (vinf.bits_per_pixel == RGB888_FMT)
{

        //定义指针
unsigned int *p = pmem;

        //指向点位置(高度*一行的像素点+宽度)
*(p + y * vinf.xres_virtual + x) = col;
}
else if (vinf.bits_per_pixel == RGB565_FMT)
{
unsigned short *p  = pmem;    
*(p + y * vinf.xres_virtual + x) = col;
}
return ;
}

main.c调用

    draw_point(400, 300, 0x00ff0000);

6、显示图片

//显示图片

  • int x, int y,        图片位置
  • char *picname,存放源图片的路径
  • int w, int h         图片的长宽

void draw_bmp(int x, int y, char *picname, int w, int h)
{
int fd = open(picname, O_RDONLY);
if (-1 == fd)
{
perror("fail open bmp");
return ;
}

lseek(fd, 54, SEEK_SET);

    unsigned char r, g, b;

    unsigned char *buff = malloc(w*h*3);
read(fd, buff, w*h*3);

unsigned char *p = buff;
for (int j = h-1; j >= 0; j--)
{
for (int i = 0; i < w; i++)
{

            b = *p; p++;
g = *p; p++;
r = *p; p++;
if (vinf.bits_per_pixel == RGB888_FMT)
{
unsigned int col = (r << 16) | (g << 8) | (b << 0);
draw_point(i+x, j+y, col);
}
else if (vinf.bits_per_pixel == RGB565_FMT)
{
unsigned short col = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);
draw_point(i+x, j+y, col);
}
}
}

    free(buff);
close(fd);
}

main.c 调用

    draw_bmp(0, 0, "./res/3.bmp", 800, 480);

  • 显示的图片还需要进行预处理(在window绘图软件进行)
    • 将图片的长宽尺寸转为板子的分辨率(长800;宽480)
    • 将图片另存为bmp:bit map(原始像素存储:前54byte 照片属性(长宽高))
    • 将图片复制进虚拟机内部,并给图片读写权限
      • 右键进入Properties
      • 将其内的Permissions 的Access权限打开为:Read and Write
    • 即可调用函数实现

7、显示字

1)字模创建(软件如图):

2)构建数组

        复制字模软件生成的取模点阵,按照下面格式写成数组

3)函数调用

4)代码实现

  • //显示字
    • //int x, int y,    在哪显示
    • //unsigned char *word,    字体的字模
    • //int w, int h,     字体大小
    • //unsigned int col    字体颜色

void draw_word(int x, int y, unsigned char *word, int w, int h, unsigned int col)
{

    for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
unsigned char tmp = word[i+j*w];
for (int k = 0; k < 8; k++)
{
if (tmp & 0x80)
{
draw_point(i*8+k+x, j+y, col);
}
else
{
//文字的背景色
}
tmp = tmp << 1;
}
}
}
}

main.c 调用

    draw_word(300, 300, dan, 24/8, 22, 0x00ff0000);

  • 24/8 :
    • 24->宽(最好是8的整数倍,一般字模软件生成会调整)
    • 8 固定
  •  22:高

8、显示一段话(字库)

        一段话一直一个单个字取模很麻烦,所以引入字库;

        linux:一个汉字、两个字节

1)创建字库(软件如图):

2)初始化字库

3)查看字库权限

4)调用函数

5)代码实现

//显示一段话

int draw_utf8_str(UTF8_INFO *info, int arg_x, int arg_y,  char* zi, unsigned int col, unsigned int col1)
{
char* temp = zi;
unsigned int x = arg_x ;
unsigned int y =  arg_y;

    while(*temp != '\0')
{
int ret = draw_utf8(info, x, y, temp, col, col1);
x += info->width;
if(x > vinf.xres)
{
x = 0;
y += info->height;
if(y > vinf.yres)
{
y = 0;
}
}

        temp += ret;
}
return 0;
}

main.c 调用

//初始化utf8字库
UTF8_INFO utf8_info;
bzero(&utf8_info, sizeof(UTF8_INFO));
strcpy(utf8_info.path, ZIKUK_FILE_BIG);
utf8_info.width = 32;
utf8_info.height = 32;
init_utf8(&utf8_info);

//调用

    draw_utf8_str(&utf8_info, 100, 100, "2025年10月8号", 0x00ff0000, 0x00ffffff);

http://www.dtcms.com/a/457763.html

相关文章:

  • 手机版免费申请微网站赣州新闻联播视频
  • 西安市做网站的公司新东方雅思培训机构官网
  • n8n工作流配置初解
  • 山东嘉祥做网站的有哪几家跳转网站
  • 如何用表格做网站焦作高端网站建设
  • 【PPT】导出高清晰度图片(dpi支持自定义)-超简单图文实操-修改注册表
  • 相册在线设计平台专业seo培训学校
  • postgresql分区表代码创建方案
  • 做推广送网站免费建站设计公司企业画册
  • 甘肃省建设厅执业资格注册中心网站通知网站建设和维护怎么学
  • 【VSCode】Visual Studio Code
  • 网站建设公司哪家强网站权重提升
  • Python Web开发中的WSGI与ASGI:从传统到现代的接口演进
  • PostgreSQL索引选B-Tree还是GiST?“瑞士军刀”和“多面手”的差别你居然还不知道?
  • 链表经典算法题详解教程
  • 唐山网站建设汉狮怎么样上海牛人岛企业服务有限公司
  • 微网站开发平台wizi网站建设板块如何分类
  • 【材料学python入门】conda、 jupyter、cpu、GPAW、wsl、ubuntu
  • 完整酒店网站开发威海建设网站
  • 高速采集卡ESD方案介绍及验证
  • 建个公司网站一年多少钱wordpress ios7教程
  • 做网站有2个前提条件 一个是网站godaddy做网站
  • 手机网站和微信网站的区别潍坊企业网站建设
  • Qt 支持的绿色系英文颜色(Green Family)
  • 找代做海报的网站广西建筑模板
  • 网站icp备案费用门户网站创新的方式有
  • 购买商标去哪个网站个人所得税app下载
  • Fedora 38 安装 perl-JSON RPM 包步骤(含依赖问题解决及附安装包)​
  • 大岭山建设网站wordpress cx udy
  • 电阻的分类与应用