当前位置:   article > 正文

LCD(GEC6818)_gec6818开发板

gec6818开发板

此篇博客是基于GEC6818开发板使用

1、液晶屏的基本概念

像素:屏幕上显示颜色的最小单位,英文叫pixel。注意,位图(jpg,bmp等格式的常见图片)也是由一个个的像素点构成的,跟屏幕的像素点的概念一样。原理上讲,将一张位图显示到屏幕上,就是将图片上的像素点一个个复制到屏幕像素点。

分辨率:宽高两个像素点。分辨率越高,所需要的显存越大

色深:每个像素点所对应的内存字节数,一般有8位、16位、24位或32位

 GEC6818开发板的屏幕的色深是32位的

32位色深的屏幕一般被称为真彩屏,或1600万色屏

色深决定了一个像素点所能表达的颜色的丰富程度,色深越大,色彩表现力越强

2、lcd

lcd的设备名字:/dev/fb0                (fb=framebuffer 帧缓冲)

开发板和虚拟机都在该路径下

lcd的分辨率(lcd的大小):800 * 480(像素点)

将像素点转化为字节单位(1个像素点等于4个字节)

1个像素点1等于ARGB(4个字节)

A-->透明度(决定颜色的深浅,实际要看硬件的参数是否有)

R-->red

G-->green

B-->blue

说明:挑选颜色=windows的画图软件+计算器(程序员)

  1. struct fb_fix_screeninfo
  2. {
  3. char id[16]; /* identification string eg "TT Builtin" */
  4. unsigned long smem_start; /* Start of frame buffer mem */
  5. /* (physical address) */
  6. __u32 smem_len; /* Length of frame buffer mem */
  7. __u32 type; /* see FB_TYPE_* */
  8. __u32 type_aux; /* Interleave for interleaved Planes */
  9. __u32 visual; /* see FB_VISUAL_* */
  10. __u16 xpanstep; /* zero if no hardware panning */
  11. __u16 ypanstep; /* zero if no hardware panning */
  12. __u16 ywrapstep; /* zero if no hardware ywrap */
  13. __u32 line_length; /* length of a line in bytes */
  14. ...
  15. ...
  16. };
  17. struct fb_var_screeninfo
  18. {
  19. __u32 xres; /* 可见区宽度(单位:像素) */
  20. __u32 yres; /* 可见区高度(单位:像素) */
  21. __u32 xres_virtual; /* 虚拟区宽度(单位:像素) */
  22. __u32 yres_virtual; /* 虚拟区高度(单位:像素) */
  23. __u32 xoffset; /* 虚拟区到可见区x轴偏移量 */
  24. __u32 yoffset; /* 虚拟区到可见区y轴偏移量 */
  25. __u32 bits_per_pixel; /* 色深 */
  26. // 像素内颜色结构
  27. struct fb_bitfield red; // 红色
  28. struct fb_bitfield green; // 绿色
  29. struct fb_bitfield blue; // 蓝色
  30. struct fb_bitfield transp;// 透明度
  31. ...
  32. ...
  33. };
  34. struct fb_bitfield
  35. {
  36. __u32 offset; /* 颜色在像素内偏移量 */
  37. __u32 length; /* 颜色占用数位长度 */
  38. ...
  39. ...
  40. };
  41. //上述结构体的具体定义在系统的如下路径中
  42. /usr/include/linux/fb.h

3、lcd刷颜色操作

lcd刷颜色是最基本的使用,步骤一共有四步:

1、打开lcd

2、填充刷lcd的buf

3、将buf写到lcd中

4、关闭lcd

实现代码如下

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. int main(int argc,char** argv)
  8. {
  9. //1、打开lcd
  10. int fd_lcd,ret; // ---> lcd也是一个文件,需要使用一个文件描述符
  11. fd_lcd = open("/dev/fb0",O_RDWR);
  12. if(fd_lcd == -1)
  13. {
  14. perror("open lcd fail");
  15. return -1;
  16. }
  17. //2、填充刷lcd的buf
  18. //方法一
  19. //int buf[800*480] = { 0 };
  20. //int color = 0x00ffffff; //刷图的颜色
  21. //for(int i = 0;i < 800*480;i++)
  22. //{
  23. // buf[i] = color;
  24. //}
  25. //方法二
  26. int buf[800*480] = {0};
  27. //给这一个buf的每一个像素点赋值
  28. int x=0; //x表示lcd的横轴
  29. int y=0; //y表示lcd的纵轴
  30. //用xy表示LCD的每一个像素点,然后一行一行的写(从第0行开始写)
  31. for(y=0;y<480;y++)
  32. {
  33. for(x=0;x<800;x++)
  34. {
  35. //y=0 x=0 第0行第0个像素点
  36. //y=1 x=1 第1行的第1个像素点(4个字节)
  37. buf[y*800+x] = green;
  38. }
  39. }
  40. //3、将buf写到lcd中
  41. write(fd_lcd,buf,sizeof(buf));
  42. //4、关闭lcd
  43. close(fd_lcd)
  44. return 0
  45. }

4、内存映射

为什么要使用内存映射呢?

当我们使用普通的read,write函数读写lcd时,发现lcd显示颜色的时候:

1、逐渐显示的过程

2、每条颜色之间存在毛刺的现象

3、显示颜色的时间稍长

这就引出内存映射(mmap)这种方法,内存映射函数接口如下:

  1. //mmap()函数 ---> man 2 mmap
  2. //功能:将文件或设备映射到内存中
  3. #include <sys/mman.h>
  4. void* mmap(void* addr,size_t length,int port,int flag,int fd,off_t offset);
  5. 参数说明:
  6. addr:不为NULL ---> 用户选择内存空间的起始地址 0.00001%
  7. NULL ---> 系统为用户去自动分配某一块空间 99.99999%
  8. length:映射的内存大小(字节数)
  9. port:PROT_EXEC 页面可能会被执行
  10. PROT_READ 可以阅读页面
  11. PROT_WRITE 可以写页面
  12. PROT_NONE 页面可能无法访问
  13. 如果需要多个权限,则使用“ | ” 连接在一起
  14. flag:MAP_SHARED: 1、进程共享内存 2、内存数据的变更同步到对应的文件
  15. MAP_PRIVATE: 1、内存私有 2、内存数据的变更不会影响到对应的内存
  16. fd:文件描述符
  17. offset:文件偏移量(从文件的哪个地方开始进行映射)
  18. 返回值:成功:指向那片内存空间的区域的地址
  19. 失败:NULL
  20. //munmap()函数 ---> man 2 munmap
  21. //功能:将文件或设备取消映射到内存
  22. #include <sys/mman.h>
  23. int munmap(void* addr,size_t length);
  24. 参数说明:
  25. addr:需要撤销映射的内存的起始地址 ---> mmap()函数的返回值
  26. length:撤销的长度
  27. 返回值:成功:0DD
  28. 失败:-1
  29. 每次lcd映射完完了之后需要释放掉 ---> 使用munmap()函数

内存映射的实现步骤:

1、打开lcd(open)

2、内存映射(mmap)

3、操作映射空间

4、取消内存映射(munmap)

5、关闭lcd(close)

测试代码如下:

  1. #include <stdio.h>
  2. #include <sys/mman.h>
  3. #inclued <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. int main(int argc,char** agrv)
  8. {
  9. int fd_lcd;
  10. int* addr = NULL;
  11. int color = 0x00ff00ff;
  12. //1、打开lcd(open)
  13. fd_lcd = open("/dev/fb0",O_RDWR);
  14. if(fd_lcd == -1)
  15. {
  16. perror("open lcd fail");
  17. return 0;
  18. }
  19. //2、内存映射(mmap)
  20. addr = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd_lcd,0);
  21. if(addr == NULL)
  22. {
  23. perror("mmap fail");
  24. return -1;
  25. }
  26. //3、操作映射空间
  27. /*开始操作这段映射空间*/
  28. //给指针指向的这段空间赋值(效率要高于读写LCD)
  29. int x=0;//x是横轴
  30. int y=0;//y是纵轴
  31. //一行一行的给指针指向的像素点赋值
  32. for(y=0;y<480;y++)
  33. {
  34. for(x=0;x<800;x++)
  35. //指针偏移是指向的下一个单位
  36. //先指针偏移然后解引用
  37. *(addr+y*800+x) = color; //颜色
  38. }
  39. //4、取消内存映射(munmap)
  40. munmap(addr,800*480*4);
  41. //5、关闭lcd(close)
  42. close(fd_lcd);
  43. return 0;
  44. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/398911
推荐阅读
相关标签
  

闽ICP备14008679号