屏幕控制(LCD和触摸屏)
LCD显示
- 打开LCD屏幕
open需要包含的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd_lcd = open("/dev/fb0", O_RDWR);
- 建立映射,将LCD文件映射到一片内存
mmap需要包含的头文件
#include <sys/mman.h>
unsigned int * plcd = mmap( NULL, //是否指定内存
heigh_lcd*width_lcd*4, //申请内存的大小
PROT_READ | PROT_WRITE, //申请内存的权限
MAP_SHARED, //内存是否共享
fd_lcd, //文件描述符
0); //偏移量
显示bmp格式图片
bmp格式的图片是没有经过压缩的的图片,所以打开的方式较为简单。
- 打开bmp图片
int fd_bmp = open("./pic.bmp", O_REWR);
- 将图片映射到一片内存
unsigned char * pbmp = mmap(NULL, //是否指定内存
heigh_bmp*width_bmp*3, //申请内存的大小
PROT_READ | PROT_WRITE, //申请内存的权限
MAP_SHARED, //内存是否共享
fd_bmp, //文件描述符
0); //偏移量
- 读取图片的数据,然后写入LCD
int x, y;
//逐行写入
for(y=0; y<heigh_lcd; y++){
//逐点写入
for(x=0; x<width_lcd; x++){
//合成像素点
*(plcd + x + width*y) = (*(pbmp + 0 + 3*x + width*y) << 0) | \
(*(pbmp + 1 + 3*x + width*y) << 8) | \
(*(pbmp + 2 + 3*x + width*y) << 16);
}
}
- 关闭文件,结束内存映射
close(fd_lcd);
close(fd_bmp);
munmap(plcd, heigh*width*4);
munmap(pbmp, heigh*width*3);
显示jpeg格式图片
- 安装jpg库
在虚拟机中
//解压文件
tar -zxvf jpegsrc.v9a.tar.gz
cd jpeg-9a/
注意,解压应该在非共享目录下进行,否则会使软链接失效。
//对jpeg源码进行配置
./configure --host=arm-linux --prefix=/home/gec/jpeglib
make
make install
//把虚拟机中的jpeglib目录拷贝到开发板文件系统中的根目录下
/jpgelib
//修改开发板中的配置脚本/etc/profile
vi /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/jpeglib/lib
//重启开发板
- 解压缩jpg格式图片
1)为JPEG对象分配空间并初始化
2)指定解压缩数据源
3)获取文件信息
4)为解压缩设定参数,包括图片大小,颜色空间
5)开始解压缩
6)取出数据
7)解压缩完成
8)释放资源
1)为JPEG对象分配空间并初始化,解压缩过程中使用的JPEG对象是一个jpeg_decompress_struct的结构体。同时还需要定义一个用于错误处理的结构体对象,IJG中标准的错误结构体是jpeg_error_mgr
struct jpeg_decompress_struct dinfo;
struct jpeg_error_mgr jerr;
然后是将错误处理结构对象绑定在JPEG对象上
dinfo.err = jpeg_std_error(&jerr);
初始化dinfo结构
jpeg_create_decompress(&dinfo);
2)指定解压缩数据源,利用标准C中的文件指针传递要打开的jpg文件
FILE *infile;
if ((infile= fopen(argv[1], "w")) == NULL)
return 0;
//图片名通过main函数的参数传到main函数,使用:./show_jpg a.jpg
jpeg_stdio_src(&dinfo, infile);
3)获取文件信息,IJG将图像的缺省信息填充到dinfo结构中以便程序使用
jpeg_read_header(&dinfo, TRUE);
此时,常见的可用信息包括图像的
宽dinfo.image_width,
高dinfo.image_height,
色彩空间dinfo.jpeg_color_space,
颜色通道数dinfo.num_components等。
4)为解压缩设定参数,在完成jpeg_read_header调用后,开始解压缩之前就可以进行解压缩参数的设定,也就是为dinfo结构的成员赋值。
比如可以设定解出来的图像的大小,也就是与原图的比例。使用scale_num和scale_denom两个参数,解出来的图像大小就是scale_num/scale_denom,但是IJG当前仅支持1/1, 1/2, 1/4,和1/8这几种缩小比例。
比如要取得1/2原图的图像,需要如下设定:
dinfo.scale_num=1;
dinfo.scale_denom=2;
也可以设定输出图像的色彩空间,即dinfo.out_color_space,可以把一个原本彩色的图像由真彩色JCS_RGB变为灰度JCS_GRAYSCALE。如:
dinfo.out_color_space=JCS_GRAYSCALE;
5)开始解压缩根据设定的解压缩参数进行图像解压缩操作。
(void)jpeg_start_decompress(&dinfo);
在完成解压缩操作后,IJG就会将解压后的图像信息填充至dinfo结构中。比如,输出图像宽度dinfo.output_width,输出图像高度dinfo.output_height,每个像素中的颜色通道数dinfo.output_components(比如灰度为1,全彩色为3)等。
6)取出数据,解开的数据是按照行取出的,数据像素按照scanline来存储,scanline是从左到右,从上到下的顺序,每个像素对应的各颜色或灰度通道数据是依次存储,比如一个24-bitRGB真彩色的图像中,一个scanline中的数据存储模式是R,G,B,R,G,B,R,G,B,…,每条scanline是一个JSAMPLE类型的数组,一般来说就是unsigned char,定义于jmorecfg.h中。
//申请一片可以储存一行图片数据的内存
unsigned char *buffer=(unsigned char*)malloc(dinfo.output_width*3);
int i,j=0;
//逐行读取
while(dinfo.output_scanline<dinfo.output_height){
//逐点读取
jpeg_read_scanlines(&dinfo, &buffer, 1);
for(x=0; x<dinfo.output_width; x++){
//合成并显示像素点
*(plcd+y*800+x) = (*(buffer+0+3*x)<<0) | (*(buffer+1+3*x)<<8) | (*(buffer+2+3*x)<<16);
}
y++;
}
7)解压缩完毕,释放资源
jpeg_finish_decompress(&dinfo);
jpeg_destroy_decompress(&dinfo);
fclose(infile);
- 编译
arm-linux-gcc show_pic.c -o show_pic -I /home/gec/jpeglib/include/ -L /home/gec/jpeglib/lib -ljpeg
-I: 链接到头文件所在的目录(大写的i)
-L: 链接到库所在的目录
-l: 链接到库(小写的L)
触摸屏的使用
<linux/input.h>中定义的struct input_event结构体
struct input_event {
struct timeval time; //按键时间
__u16 type; //类型,在下面有定义
__u16 code; //类型下对应的事件
__s32 value; //事件所对应的值
};
type中所有的类型:
type:
EV_KEY //键盘
EV_REL //相对坐标
EV_ABS //绝对坐标
链接: 原文详见.
版权声明:本文为CSDN博主「lemontree1945」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lemontree1945/article/details/78864681
int get_ts_xy(int *ts_x, int *ts_y, int fd_ts)
{
//触摸屏所需要的结构体
struct input_event ts_buf;
//记录读取的次数
int count = 0;
//2、读取触摸屏的数据
while(1){
read(fd_ts, &ts_buf, sizeof(ts_buf));
//获取x轴坐标值
if (ts_buf.type == EV_ABS && ts_buf.code == ABS_X){
count++;
//记录读到的x坐标的值
*ts_x = ts_buf.value;
}
//获取y轴坐标值
if (ts_buf.type == EV_ABS && ts_buf.code == ABS_Y){
count++;
//记录读到的y坐标的值
*ts_y = ts_buf.value;
}
if(2 == count){
printf("(%d, %d)\n", *ts_x, *ts_y);
//延时3000ms
usleep(3000);
count = 0;
break;
}
}
}
本文仅为学习笔记,欢迎纠错