实验目的
- 利用粤嵌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;
int lcd_init()
{
fd = open(LCD_PATH,O_RDWR);
if(fd<0)
{
perror("open fail");
return -1;
}
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;
}
void lcd_close()
{
munmap(plcd,800*480*4);
close(fd);
}
void display_point(int x,int y,int color)
{
if(x >= 0 && x < 800 && y >= 0 && y < 480)
{
*(plcd + 800 * y + x) = color;
}
}
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);
}
}
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)
{
int fd = open(filename,O_RDWR);
if (-1 == fd)
{
printf("Open %s Fail!\n",filename);
perror("--->");
return -1;
}
unsigned char buf[4];
read(fd,buf,2);
if(buf[0]!= 0x42 || buf[1]!= 0x4d)
{
printf("NOT BMP\n");
goto ERROR_END;
}
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]);
if(!(depth == 24 || depth == 32))
{
printf("NOT Support!\n");
goto ERROR_END;
}
printf("%s:%d*%d depth=%d\n",filename,width,height,depth);
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++)
{
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;
}
void bmp_player(int i)
{
}
#include "touch.h"
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define TOUCH_PATH "/dev/input/event0"
int GetDirection()
{
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)
{
read(fd, &ev, sizeof(struct input_event));
if(ev.type == EV_ABS)
{
if(ev.code == ABS_X)
{
if (-1 == x_start)
{
x_start = ev.value;
}
x_end = ev.value;
}
if(ev.code == ABS_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);
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();
while (1)
{
rs = GetDirection();
printf("%d\n",rs);
if (1 == rs || 3 == rs)
{
if (5 == i)
{
i = 0;
}
else
++i;
show_bmp(bmpname[i],0,0);
}
else if (2 == rs || 4 == rs)
{
if (0 == i)
{
i = 5;
}
else
--i;
show_bmp(bmpname[i],0,0);
}
}
lcd_close();
return 0;
}
总结
- 整个工程可以正常运行,已上板测试验证,现实中图片是很清楚的,只是网站限制了只能上传5M以内,压缩了画质。GIF如下:

- 垂直切换图片

- 想要整个工程的可以到以下地方下载,有积分的小伙伴CSDN直接下载即可,没有积分的可以网盘下载。
- https://download.csdn.net/download/jianfeng_520/60963967
- 百度网盘:链接:https://pan.baidu.com/s/1_jH3jKXNjSRvEnf1itvvnA
提取码:iejv