main函数执行流程
-
1、初始化触摸屏
Touch_screen_Init();struct tsdev *ts = NULL; ts = ts_setup(NULL, 0); //以阻塞打开 -
2、初始化 LCD
LCD_Init(void);通过 ioctl 函数获取 LCD 的固定参数、可变参数,得到分辨率、bpp、一行的长度(以字节为单位),将显存映射到内存上,得到 framebuffer 的首地址,使用 memset 函数将这块区域全部设置为 1,即将LCD设置为白色背景
struct fb_var_screeninfo var; /* Current var */ struct fb_fix_screeninfo fix; /* Current fix */ ioctl(fd_fb, FBIOGET_VSCREENINFO, &var);//获取屏幕可变信息 ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix);//获取屏幕固定信息 ... unsigned char* fbbase; fbbase = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0); // 映射 screen_size:整块显存的大小 memset(fbbase, 0xFF, screem_size); -
3、打开摄像头
int fd = open("/dev/video1", O_RDWR); -
4、将背景图片1(带有拍照、相册按钮)显示在 LCD 上
LCD_Show_JPEG(background1);这个图片的分辨率是 1024 * 600(板子的屏幕的分辨率也是 1024 * 600)
-
5、将图片放入相册
将指定目录(/home/)中已有的图片(.jpg格式)加入双向链表中,image_count 为目前图片名称最大索引
image_count = xiangce_Init(); -
6、遍历链表
jpeg_list_printf(void)遍历双向链表(不包含虚拟头节点),打印所有照片的名字
-
7、设置摄像头的采集格式
struct v4l2_format vfmt; vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //选择视频抓取 // 一定是 800 * 600(600等于LCD的高度,8800于LCD的宽度是为了显示相机的按钮) vfmt.fmt.pix.width = 800;//设置宽 vfmt.fmt.pix.height = 600;//设置高 vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;//设置视频采集像素格式 int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);// VIDIOC_S_FMT:设置捕获格式 if(ret < 0) { perror("设置采集格式错误"); } // 判断是否设置成功 memset(&vfmt, 0, sizeof(vfmt)); vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_G_FMT, &vfmt); if(ret < 0) { perror("读取采集格式失败"); } printf("设置分辨率width = %d\n", vfmt.fmt.pix.width); printf("设置分辨率height = %d\n", vfmt.fmt.pix.height); unsigned char *p = (unsigned char*)&vfmt.fmt.pix.pixelformat; printf("pixelformat = %c%c%c%c\n", p[0],p[1],p[2],p[3]); -
8、申请缓冲队列
struct v4l2_requestbuffers reqbuffer; reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuffer.count = 4; //申请4个缓冲区 reqbuffer.memory = V4L2_MEMORY_MMAP; //采用内存映射的方式 ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuffer); if(ret < 0) { perror("申请缓冲队列失败"); } -
9、映射
struct v4l2_buffer mapbuffer; unsigned char *mmpaddr[4]; //用于存储映射后的首地址 unsigned int addr_length[4];//存储映射后空间的大小 mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//初始化type for(int i = 0; i < 4; i++) { mapbuffer.index = i; ret = ioctl(fd, VIDIOC_QUERYBUF, &mapbuffer); //查询缓存信息 if(ret < 0) perror("查询缓存队列失败"); mmpaddr[i] = (unsigned char *)mmap(NULL, mapbuffer.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, mapbuffer.m.offset);//mapbuffer.m.offset映射文件的偏移量 addr_length[i] = mapbuffer.length; //放入队列 ret = ioctl(fd, VIDIOC_QBUF, &mapbuffer); // 将用户空间的视频缓冲区送入内核中 if(ret < 0) perror("放入队列失败"); } -
10、打开设备(启动视频流传输)
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_STREAMON, &type); if(ret < 0) { perror("打开设备失败"); } -
11、创建线程读取触摸屏输入
pthread_t pthread_read; pthread_create(&pthread_read, NULL, start_read, NULL);线程函数:
如果点击触摸屏,并且触摸点在 “ 拍照 ” “ 相册 ” 按钮范围内,则会记录触摸点的坐标 read_x read_y(全局变量)
void *start_read(void *arg) { int x = 0, y =0; while(start_read_flag) // 初始化为1,当整个程序要退出时,设为0,退出线程 { printf("线程\n"); read_touchscreen(&x, &y); // 阻塞读取触点坐标 //拍照 if(x > 800 && x < 1000 && y > 0 && y < 600) { printf("chuli\n"); pthread_mutex_lock(&mutex); read_x = x; read_y = y; pthread_mutex_unlock(&mutex); } printf("readx = %d, ready = %d", read_x, read_y); } return NULL; }read_touchscreen 函数:
ts_read 的默认读取是以阻塞的方式
int read_touchscreen(int *x, int *y) { struct ts_sample samp; // ts_setup 以阻塞的方式打开了触摸屏设备,所以 ts_read 是阻塞读取 if (ts_read(ts, &samp, 1) < 0) // 1:代表对一个触摸点的采集数 { perror("ts_read error"); ts_close(ts); return -1; } *x = samp.x; *y = samp.y; printf("anxia : %d %d", samp.x, samp.y); return 0; } -
12、进入 while 循环,提取摄像头数据,并在LCD上显示同时实现拍照、相册功能
while(1) { //从队列中提取一帧数据 struct v4l2_buffer readbuffer; readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_DQBUF, &readbuffer); //从缓冲队列获取一帧数据(出队列) //出队列后得到缓存的索引index,得到对应缓存映射的地址mmpaddr[readbuffer.index] if(ret < 0) perror("获取数据失败"); if(read_x > 850 && read_x < 1000 && read_y > 0 && read_y < 600) { if(read_x > 850 && read_x < 1000 && read_y > 130 && read_y < 210) { printf("paizhao\n"); char newname[20] = {0}; image_count++; sprintf(newname,"/home/%d.jpg", image_count); FILE *file = fopen(newna

最低0.47元/天 解锁文章
2261

被折叠的 条评论
为什么被折叠?



