实验目的
- 利用粤嵌LinuxGEC6818开发板实现电子相册,要求如下: - 实验操作必须在Linux操作系统下完成- 源代码模块化设计- 实现水平或者垂直滑动切换图片
实验步骤
- 因为操作需要在Linux下运行,所以首先安装VM虚拟机,此次安装的系统是Ubuntu18,这里不再进行介绍。
- 涉及ARM编译,gcc编译的可执行文件,它只适合在X86架构上运行的linux上运行,并不能在ARM架构上的linux上运行。所以需要采用交叉开发。
交叉开发- 有些产品(或设备)并不适合编辑编译代码。比如:51单片机,STM32… 把编辑编译和运行分开,我们在X86的机器上(电脑)编辑编译代码,再把可执行文件传输到产品(或设备)上运行。- gcc编译的可执行文件,它只适合在X86架构上运行的linux上运行。并不能在ARM架构上的linux上运行。 arm-linux-gcc编译的文件只适合在arm架构上的linux上运行。
- 因为需要让屏幕显示内容,必须先对屏幕进行坏点测试,排除屏幕坏点问题,全屏显示蓝色,程序如下:
#include"lcd.h"/*宏定义*/#defineBLUE0x0000FF#defineLCD_PATH"/dev/fb0"//全局变量int fd =-1;int*plcd =NULL;//lcd初始化intlcd_init(){//1.打开屏幕文件
fd =open(LCD_PATH,O_RDWR);//可读可写打开if(fd<0){perror("open fail");return-1;}//2.映射
plcd =mmap(NULL,800*480*4,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,0);if(plcd == MAP_FAILED){perror("MAP fail");return-1;}return0;}//LCD关闭voidlcd_close(){munmap(plcd,800*480*4);close(fd);}//指定的点上显示指定的颜色voiddisplay_point(int x,int y,int color)//x为高,y为宽{if(x >=0&& x <800&& y >=0&& y <480){*(plcd +800* y + x)= color;}}//LCD测试voidlcd_test(){lcd_init();int x,y;for(y=0;y<480;y++)//遍历每一行{for(x=0;x<800;x++)//遍历每一列{display_point(x,y,BLUE);}}// //写数据// write(fd,color,480*800*4);lcd_close(fd);}
- 确认屏幕没有坏点后,可以将图片写入屏幕中,让屏幕显示图片,在主函数中调用
show_bmp(char * filename,int x0,int y0)
,即可显示让屏幕图片,filename为文件名,x0跟y0是屏幕显示的起始坐标,左上角为起始位(0,0)。程序如下:
#include"Bmp.h"#include"lcd.h"//显示图片intshow_bmp(char* filename,int x0,int y0){//1.打开bmp图片int fd =open(filename,O_RDWR);//判断读入图片是否错误if(-1== fd){printf("Open %s Fail!\n",filename);perror("--->");return-1;}//2.判断到底是不是一张bmp图片unsignedchar buf[4];read(fd,buf,2);if(buf[0]!=0x42|| buf[1]!=0x4d)//若果不是B M 的ASCII码{printf("NOT BMP\n");goto ERROR_END;}//3.读取数据int width,height;short depth;lseek(fd,0x12,SEEK_SET);read(fd,buf,4);
width=(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|(buf[0]);lseek(fd,0x16,SEEK_SET);read(fd,buf,4);
height=(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|(buf[0]);lseek(fd,0x1c,SEEK_SET);read(fd,buf,2);
depth=(buf[1]<<8)|(buf[0]);//只支持色深为24和32的if(!(depth ==24|| depth ==32)){printf("NOT Support!\n");goto ERROR_END;}printf("%s:%d*%d depth=%d\n",filename,width,height,depth);//4.获取像素数组int line_valid_bytes =abs(width)*depth/8;//一行有效字节数int line_bytes;//一行总字节数=有效字节数+赖子数 int laizi =0;if(line_valid_bytes%4){
laizi =4-line_valid_bytes%4;}
line_bytes = line_valid_bytes + laizi;int total_bytes = line_bytes*abs(height);//整个像素数组的大小//开辟一块动态内存unsignedchar*piexl =(unsignedchar*)malloc(total_bytes);//用完后需要释放内存lseek(fd,54,SEEK_SET);read(fd,piexl,total_bytes);unsignedchar a,r,g,b;int color;int i =0;int x,y;for(y=0;y<abs(height);y++){for(x=0;x<abs(width);x++){//a r g b 0xargb 小端模式 b g r a
b = piexl[i++];
g = piexl[i++];
r = piexl[i++];if(depth ==32){
a = piexl[i++];}else{
a =0;//不透明}
color=(a<<24)|(r<<16)|(g<<8)|(b);//在屏幕对应的位置显示display_point(width>0?x0+x:x0+abs(width)-x-1,
height>0?y0+abs(height)-y-1:y0+y,
color);}//每一行的末尾 有可能填充几个赖子
i += laizi;}//释放内存free(piexl);//关闭显示close(fd);
ERROR_END:close(fd);return-2;}//图片数组// char * bmpname[] = {"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp"};//循环显示图片voidbmp_player(int i){// int i = 0;// while (1)// {//循环显示// show_bmp(bmpname[i],0,0);// 延时5s// sleep(5);// i++;// if (6 == i)// {// i = 0;// }// }}
- 接下来获取手指触摸触摸坐标,程序如下:
#include"touch.h"#defineUP1#defineDOWN2#defineLEFT3#defineRIGHT4//宏定义//设备文件#defineTOUCH_PATH"/dev/input/event0"intGetDirection(){//1.打开触摸屏 lcd_init();int fd =open(TOUCH_PATH,O_RDONLY);//只读打开if(fd<0){perror("open fail");return0;}int x_start=-1,y_start=-1;//坐标的初值int x_end =-1,y_end =-1;//坐标终点structinput_event ev;while(1){//2.不停地从文件中读取数据read(fd,&ev,sizeof(structinput_event));//3.解析数据if(ev.type == EV_ABS)//触摸事件 {if(ev.code == ABS_X){if(-1== x_start)//x轴{
x_start = ev.value;//起点}
x_end = ev.value;//终点}if(ev.code == ABS_Y)//y轴{if(-1== y_start){
y_start = ev.value;}
y_end = ev.value;//终点}if(ev.code ==ABS_PRESSURE && ev.value ==0){if(x_start !=-1&& y_start !=-1){break;}}}if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value ==0)//按键事件{if(x_start !=-1&& y_start !=-1){break;}}if(abs(x_end - x_start)>(y_end - y_start)){if(x_end - x_start >0){return4;}else{return3;}}if(abs(x_end - x_start)<(y_end - y_start)){if(y_end - y_start >0){return2;}else{return1;}}}//打印坐标printf("%d , %d\n", x_end, y_start);//4.关闭触摸屏lcd_close();}
- 获得手指滑动坐标后,终点坐标减去手指滑动起始坐标,即可判断手指是左滑、右滑还是上滑、下滑,随即再做下切换的图片的指令即可,程序如下:
#include"lcd.h"#include"Bmp.h"#include"touch.h"char* bmpname[]={"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp"};//主函数intmain(int argc,charconst*argv[]){int rs =0;int i =0;//打开屏幕lcd_init();//单独显示一张图片// show_bmp("1.bmp",0,0);//触摸while(1){// bmp_player(i);
rs =GetDirection();printf("%d\n",rs);if(1== rs ||3== rs){if(5== i){
i =0;}else++i;show_bmp(bmpname[i],0,0);// bmp_player(i);}// show_bmp(bmpname[3],0,0);elseif(2== rs ||4== rs){if(0== i){
i =5;}else--i;// bmp_player(i);show_bmp(bmpname[i],0,0);}}//循环显示// bmp_player();//关闭屏幕lcd_close();return0;}
总结
- 整个工程可以正常运行,已上板测试验证,现实中图片是很清楚的,只是网站限制了只能上传5M以内,压缩了画质。GIF如下:
- 垂直切换图片
- 想要整个工程的可以到以下地方下载,有积分的小伙伴CSDN直接下载即可,没有积分的可以网盘下载。
- https://download.csdn.net/download/jianfeng_520/60963967
- 百度网盘:链接:https://pan.baidu.com/s/1_jH3jKXNjSRvEnf1itvvnA 提取码:iejv
本文转载自: https://blog.csdn.net/jianfeng_520/article/details/121874245
版权归原作者 Jeff·Ray 所有, 如有侵权,请联系我们删除。
版权归原作者 Jeff·Ray 所有, 如有侵权,请联系我们删除。