1. 程式人生 > >itop4412之4.3寸LCD Framebuffer顯示顏色

itop4412之4.3寸LCD Framebuffer顯示顏色

使用交叉編譯工具,編譯後,用nfs傳到開發板直接執行,可在最小系統下執行,自適應RGB565,RBG888,16位,24位,32位。

程式碼如下:

/* 在LCD上顯示單色 */
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

#define RED_COLOR565     0xf800
#define GREEN_COLOR565   0x07e0
#define BLUE_COLOR565    0x001f

#define RED_COLOR888_32bpp     0x00ff0000
#define GREEN_COLOR888_32bpp   0x0000ff00
#define BLUE_COLOR888_32bpp    0x000000ff

#define RGB888_RED       0x00ff0000
#define RGB888_GREEN     0x0000ff00
#define RGB888_BULE      0x000000ff

#define RGB565_RED       0xf800
#define RGB565_GREEN     0x07e0
#define RGB565_BLUE      0x001f

static unsigned short RGB8888ToRGB565(unsigned int n888Color)
{
  unsigned short n565Color = 0;

  unsigned char cRed, cGreen, cBlue;

  cRed   = (n888Color & RGB888_RED) >> 19;
  cGreen = (n888Color & RGB888_GREEN) >> 10;
  cBlue  = (n888Color & RGB888_BULE) >> 3;

  n565Color = (cRed << 11) + (cGreen << 5) + (cBlue << 0);

  return n565Color;
}

static unsigned int RGB565ToRGB888(unsigned short n565Color)
{
  unsigned int n888Color = 0;

  unsigned char cRed, cGreen, cBlue;

  cRed   = (n565Color & RGB565_RED) >> 8;
  cGreen = (n565Color & RGB565_GREEN) >> 3;
  cBlue  = (n565Color & RGB565_BLUE) << 3;

  n888Color = (cRed << 16) + (cGreen << 8) + (cBlue << 0);

  return n888Color;
}

int main(void)
{
  int fd_fb = 0;
  struct fb_var_screeninfo vinfo;
  struct fb_fix_screeninfo finfo;
  long int screen_size = 0;
  int *fbp565 = NULL;
  unsigned int RED_COLOR888, GREEN_COLOR888, BLUE_COLOR888;
  int x = 0, y = 0;

  fd_fb = open("/dev/fb0", O_RDWR);
  if(!fd_fb)
  {
    printf("Error:cannot open framebuffer device.\n");
    return -1;
  }

  /* Get fixed screen info */
  if(ioctl(fd_fb, FBIOGET_FSCREENINFO, &finfo))
  {
    printf("Error reading fixed information.\n");
    return -2;
  }

  /* Get variable screen info */
  if(ioctl(fd_fb, FBIOGET_VSCREENINFO, &vinfo))
  {
    printf("Error reading variable information.\n");
    return -3;
  }

  screen_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
  printf("screen_size = %d, vinfo.xres = %d, vinfo.yres = %d, vinfo.bits_per_pixel = %d\n", screen_size, vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

  /* map framebuffer to user memory */
  fbp565 = (int *)mmap(0, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);

  if((int)fbp565 == -1)
  {
    printf("Error: failed to map framebuffer device to memory.\n");
    return -4;
  }
  
  if(vinfo.bits_per_pixel == 16)
  {
    printf("16 bpp framebuffer\n");
    //Red Screen
    printf("Red Screen\n");
    for(y = 0; y < vinfo.yres / 3; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = RED_COLOR565;
      }
    }
    //Green Screen
    printf("Green Screen\n");
    for(y = vinfo.yres / 3; y < (vinfo.yres * 2) / 3; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = GREEN_COLOR565;
      }
    }
    //Blue Screen
    printf("Blue Screen\n");
    for(y =  (vinfo.yres * 2) / 3; y < vinfo.yres; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = BLUE_COLOR565;
      }
    }
  }
  else if(vinfo.bits_per_pixel == 24)
  {
    RED_COLOR888   = RGB565ToRGB888(RED_COLOR565);
    GREEN_COLOR888 = RGB565ToRGB888(GREEN_COLOR565);
    BLUE_COLOR888  = RGB565ToRGB888(BLUE_COLOR565);

    printf("24 bpp framebuffer\n");
    //Red Screen
    printf("Red Screen\n");
    for(y = 0; y < vinfo.yres / 3; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = RED_COLOR888;
      }
    }
    //Green Screen
    printf("Green Screen\n");
    for(y = vinfo.yres / 3; y < (vinfo.yres * 2) / 3; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = GREEN_COLOR888;
      }
    }
    //Blue Screen
    printf("Blue Screen\n");
    for(y =  (vinfo.yres * 2) / 3; y < vinfo.yres; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = BLUE_COLOR888;
      }
    }  
  }
  else if(vinfo.bits_per_pixel == 32)
  {
    printf("32 bpp framebuffer\n");
    //Red Screen
    printf("Red Screen\n");
    for(y = 0; y < vinfo.yres / 3; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = RED_COLOR888_32bpp;
      }
    }
    //Green Screen
    printf("Green Screen\n");
    for(y = vinfo.yres / 3; y < (vinfo.yres * 2) / 3; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = GREEN_COLOR888_32bpp;
      }
    }
    //Blue Screen
    printf("Blue Screen\n");
    for(y =  (vinfo.yres * 2) / 3; y < vinfo.yres; y++)
    {
      for(x = 0; x < vinfo.xres; x++)
      {
        *(fbp565 + y * vinfo.xres + x) = BLUE_COLOR888_32bpp;
      }
    }  
  }
  else
  {
    printf("Warnning: bpp is not 16 and 24 and 32\n");
  }

  munmap(fbp565, screen_size);
  close(fd_fb);
  return 0;
}