lcd屏幕的显示原理
我们常说开发板的屏幕是800*480的
单位是什么? 像素点!
屏幕一行有800个像素点
一列有480个像素点。
像素点? 显示颜色的点

怎么让像素点显示自己想要的颜色?
OS规定: 一个 像素点由4个字节的大小来表示
这四个字节分别是什么呢?
A : 透明度 一般为0
R : Red 红色
G : Green 绿色
B : Blue 蓝色

RGB : 光的三基色
把这三种颜色 按照不同的比例混合
是不是就可以得到任何的颜色
A R G B 各占一个字节的大小
无符号一个字节(8bit)能表示的范围是多少?
0000 0000 1111 1111 1 0000 0000 - 1
0 ~ 255

也即是说:
假设我给A = 0 R =0 G = 0 B = 255
那么像素点应该显示最蓝色
如果要显示最红?
A = 0 R = 255 G = 0 B = 0

我们把这种用数字的范围来表示颜色的深浅的操作叫做颜色的量化

16进制 的一位 表示2进制的4位
假设我现在要用16进制表示最红
0x 0 255 0 0
0x A R G B
0x 00 ff 00 00

此时 也就是说 如果我想要给一个像素点上最红
那么我只需要将0X00ff0000写到像素点对应的控制点去

现在的问题是怎么写?
1. 写到哪里?

开发板有一个专门的屏幕文件 写到该文件里面就行
“/dev/fb0”
2. 怎么写?
linux的一句设计哲学
everything is file in linux
所有事物都是 文件 在linux下。
那么这意味着 我只需要学会操作文件的方法 我就可以操作linux下的一切。

第一步打开文件 open
linux手册
man 页数 要查的函数
在这里插入图片描述

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);

函数功能: 打开一个指定文件
头文件:如上
参数列表:
pathname:path:路径 name 名字
路径名 带路径的文件的名字
例子:
我要打开屏幕文件
/dev/fb0

        flags:标志 决定你对打开文件的权限
        o_RDONLY :只读
        o_WRONLY:只写
        o_RDWR:可读可写

返回值:
成功返回文件描述符(大于2的正整数)失败返回-1
打开屏幕文件代码:

		int fd;
		fd=open("/dev/fb0",O_RDWR);
		if(fd==-1)
{
    perror("失败");//perror会把错误原因告诉你(英文)
    return -1;
}

第二步 :读文件内容 read 写文件 write

 #include <unistd.h>
 int write(int fd, const void *buf, int count);

函数功能: 往文件写入内容
头文件:如上
参数列表:
fd:文件描述符 open函数的返回值
表示一个打开的文件
buf:指向一段空间 这段空间用来保存你要写入的数据
count:表示你要写入多少字节数据
返回值:
成功返回实际写入的字节数 失败返回-1
int write(int fd, const void *buf, int count);

第三步:关闭文件 close
close(fd);
close只有一个参数 就是那个已经打开的文件的文件描述符

实现
在开发板屏幕上显示粉色

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include <unistd.h>
int main()
{
int i=0;
int j=0;
int color[480][800]={0};
int fd=open("/dev/fb0", O_RDWR);
if(fd==-1)
{
	perror("open error\n");
	return -1;
}
for(i=0;i<480;i++)
{
	for(j=0;j<800;j++)
		{
		color[i][j]=0x00ffc0cb;
	}
}
write(fd,color,800*480*4);
close(fd);
}

在开发板屏幕上显示德国国旗

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
	int fd = open("/dev/fb0",O_RDWR);
	if(fd == -1){
		perror("open error\n");
		return -1;
	}

	int buf[480][800];
	for(int i=0; i<480; i++)
	{
		for(int j=0; j<800; j++)
		{
			if(i<=160)
			{
				buf[i][j] = 0x00000000;
			}
			else if(i>160 && i<=320){
				buf[i][j] = 0x00ff0000;
			}
			else
			{
				buf[i][j] = 0x00FFD700;
			}
		}
	}
	int d = write(fd,buf,800*480*4);
	if(d == -1)
	{
		perror("open error\n");
		return -1;
	}

	close(fd);
}

在开发板屏幕上显示圆

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
	int fd = open("/dev/fb0",O_RDWR);
	if(fd == -1)
	{
		perror("open error\n");
		return -1;
	}
	int buf[480][800];
	for(int i=0; i<480; i++)
	{
		for(int j=0; j<800; j++)
		{
			if(0.8*(i-240)*(i-240)+(j-400)*(j-400) <= 150*150)
			{
				buf[i][j] = 0x00000000;
			}
			else
			{
				buf[i][j] = 0x00FFD700;
			}
		}
	}
	int d = write(fd,buf,800*480*4);
	if(d == -1)
	{
		perror("open error\n");
		return -1;
	}
	close(fd);
}

在开发板上显示太极图
思路:两个左右黑白的半圆合成一个大圆,然后在同一条直径上画上下两个直径为大圆一半的圆,再在两个圆中画两个小圆

//画圆
void draw_round(int x,int y,int r,int color)
{
    for(int i=0;i<480;i++)
    {
        for(int j=0;j<800;j++)
        {
            if((i-y)*(i-y)+(j-x)*(j-x) <=r*r)
            {
                *(addr +i*800 +j)=color;
            }
        }
    }
}

//画左半圆
static void draw_Halfround_L(int x,int y,int r,int color)
{
   for(int i=0;i<480;i++)
    {
        for(int j=0;j<800;j++)
        {
            if((i-y)*(i-y)+(j-x)*(j-x) <=r*r && j<=x)
            {
                *(addr +i*800 +j)=color;
            }
        }
    }
}

//画右半圆
static void draw_Halfround_R(int x,int y,int r,int color)
{
   for(int i=0;i<480;i++)
    {
        for(int j=0;j<800;j++)
        {
            if((i-y)*(i-y)+(j-x)*(j-x) <=r*r && j>=x)
            {
                *(addr +i*800 +j)=color;
            }
        }
    }
}

static void draw_Halfround_T(int x,int y,int r,int color)
{
   for(int i=0;i<480;i++)
    {
        for(int j=0;j<800;j++)
        {
            if((i-y)*(i-y)+(j-x)*(j-x) <=r*r && i<=y)
            {
                *(addr +i*800 +j)=color;
            }
        }
    }
}

//太极图
void draw_TaiJi(int x,int y,int r)
{
    //背景
    draw_bmp("./TaiJi.bmp",0,0);
    //大圆
   draw_Halfround_L(x,y,r,0x00000000);
   draw_Halfround_R(x,y,r,0x00FFFFFF);
    draw_round(400,140,100,0x00FFFFFF); //上圆   
    draw_round(400,340,100,0x00000000); //下圆

    draw_round(400,140,20,0x00000000); //上小圆   
    draw_round(400,340,20,0x00FFFFFF); //下小圆
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐