irpas技术客

利用粤嵌LinuxGEC6818开发板实现电子相册_Jeff·Ray_gec6818电子相册

大大的周 3967

实验目的 利用粤嵌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" /*宏定义*/ #define BLUE 0x0000FF #define LCD_PATH "/dev/fb0" //全局变量 int fd = -1; int *plcd = NULL; //lcd初始化 int lcd_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; } return 0; } //LCD关闭 void lcd_close() { munmap(plcd,800*480*4); close(fd); } //指定的点上显示指定的颜色 void display_point(int x,int y,int color) //x为高,y为宽 { if(x >= 0 && x < 800 && y >= 0 && y < 480) { *(plcd + 800 * y + x) = color; } } //LCD测试 void lcd_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" //显示图片 int show_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图片 unsigned char 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);//整个像素数组的大小 //开辟一块动态内存 unsigned char *piexl = (unsigned char *)malloc(total_bytes); //用完后需要释放内存 lseek(fd,54,SEEK_SET); read(fd,piexl,total_bytes); unsigned char 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"}; //循环显示图片 void bmp_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" #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 //宏定义 //设备文件 #define TOUCH_PATH "/dev/input/event0" int GetDirection() { //1.打开触摸屏 lcd_init(); int fd = open(TOUCH_PATH,O_RDONLY);//只读打开 if(fd<0) { perror("open fail"); return 0; } int x_start=-1,y_start=-1; //坐标的初值 int x_end = -1,y_end = -1; //坐标终点 struct input_event ev; while(1) { //2.不停地从文件中读取数据 read(fd, &ev, sizeof(struct input_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) { return 4; } else { return 3; } } if (abs(x_end - x_start) < (y_end - y_start)) { if (y_end - y_start > 0) { return 2; } else { return 1; } } } //打印坐标 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"}; //主函数 int main(int argc, char const *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); else if (2 == rs || 4 == rs) { if (0 == i) { i = 5; } else --i; // bmp_player(i); show_bmp(bmpname[i],0,0); } } //循环显示 // bmp_player(); //关闭屏幕 lcd_close(); return 0; } 总结 整个工程可以正常运行,已上板测试验证,现实中图片是很清楚的,只是网站限制了只能上传5M以内,压缩了画质。GIF如下:垂直切换图片想要整个工程的可以到以下地方下载,有积分的小伙伴CSDN直接下载即可,没有积分的可以网盘下载。https://download.csdn.net/download/jianfeng_520/60963967百度网盘:链接:https://pan.baidu.com/s/1_jH3jKXNjSRvEnf1itvvnA 提取码:iejv


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #gec6818电子相册