嵌入式开发第20、21、22、23天(触摸屏电子相册)

来源:互联网 发布:拳皇咆哮 源码 编辑:程序博客网 时间:2024/05/17 11:35

项目框架

触摸屏电子相册
1、密码登录 (9键 6位密码登陆、36键 6位随机验证码)
2、电子相册功能(有自动浏览,手动浏览,上一张,下一张、
划屏操作
      指定运用方法(用链表将当前目录下面的图片连接起来,链表采用双向循环,或者内核链表)
3、音乐播放功能(播放、暂停、上一首、下一首)
其他:全触摸操作,链表链接,不许用线程。

运用知识:linux C, 文件IO,数据结构,Bmp24图片解码,jpeg图片解码,在任意位置显示24位位图图片


项目感想

1)项目框架很重要,早早的想好项目框架,对写代码有明显的辅助作用。而且能够看到自己开发过程,每完成一个功能有激励的效果。

2)准备工作很重要,在写之前列好各种需要用到的函数原型,不需要在写的过程中还在想,这个函数怎么用。

3)每写一个函数的时候,一定要想好这个函数的功能是什么,不能写过超出这个函数功能之外的东西,因为函数是被方便多次调用的,而不是只用一次,只用一次的函数,没有存在的意义。

4)每一个功能,一个全局变量,定义名字的时候一定要有代表性,有含义,不要瞎定义,有时定义一个i ,搞得自己都不知道他是干嘛的了。

5)关键的地方一定要备注,很重要,有时灵光一闪想到的算法,过了一两天,我居然看不懂了。

6)写代码的时候,不能一次写出超过两个函数以上的功能,两个以上的时候,找BUG会非常繁琐,浪费时间,建议每写一个小功能要调试一次,只有把地基打牢,才能建起高楼,特别是在写到自己不太熟练的,一定要想好,调试好

7)习惯写调试信息,没有一个正确的反馈根本不知道自己出错在哪。而且用完以后也不要删除,注释就好,可能后面还要用呢。

8)刚开始的时候写的时候,不要把初始的功能想的太复杂,越复杂的东西越难实现,只要结果能够达到初始所设计的目标就够了。想要更智能需要重新构思。我在刚开始写26键密码按钮的时候,耗了很多时间,看到别人把9键都已经做出来了,压力更大了,也没信心写了,后来改回简单的9键,做完整个项目再慢慢加上去,觉得特别的轻松。


9)有那么一刻觉得,自己的代码是完美的,绝对是系统出错了。经过无数次打脸后,得出一个结果,永远不要怪系统出错,就是自己的错误,电脑发展至今,就是经历了无数程序员的修改,完善,不可能自己的一时想法,就超越了这么多的前人。

10)永远不要对自己的代码感到满足。同时也要对自己的代码充满信心。




#include <stdio.h>#include <fcntl.h> #include <unistd.h>#include <sys/select.h>#include <stdlib.h>#include <netdb.h>#include <string.h>#include <sys/stat.h>#include <sys/mman.h>#include "tslib.h"#include <sys/types.h>#include <dirent.h>#include <errno.h>#include <strings.h>#include "list.h"#include <time.h>#define DEV_NAME "/dev/event0"#define USR_PW "./setting/password"int g_y=0;//字母弹框int g_x=1;//操作教程int g_lcd_fd;//触摸屏显示unsigned long *g_fd_men;//显示屏的 内存映射char num[6];//密码char numm[6];//验证码char bmp[][40];//图片char mmp3[][40];//音乐void picture_or_music(void); //声明选项//链表--------------OPEN----------------------//设计节点 双向链表typedef struct node{char bmpp[40];struct node *prev;struct node *next;}listnode,*double_list;  //listnode = struct node  ,double_list = struct node *//2、初始化空链表double_list init_list(void){double_list head = malloc(sizeof(listnode)); //开辟节点空间if(head == NULL){printf("malloc node failed!\n");return NULL;}head->prev = head->next = head;return head;}//3、插入节点void insert_node(double_list new,double_list p){if(new == NULL || p == NULL)return;new->prev = p;  //第一步new->next = p->next; //第二步p->next = new;//第三步new->next->prev = new;  //第四步}//3、显示链表操作void show(double_list head){if(head == NULL)return;double_list p = head->next;while(p!=head){printf("%s\n",p->bmpp);p = p->next;}}//链表--------------END--------------------//读文件路径   id=1  读图片   id=2  读音乐int dir(int id){DIR *dir;int i=0;   struct dirent *tmp;    struct dirent *tmp2;   //打开目录   if(id==1)   dir = opendir("/coolAlbum/picture");   if(id==2)   dir = opendir("/coolAlbum/music");         if(dir == NULL)   {   perror("opendir!\n");   return -1;   }      //读目录  计算数量   while((tmp = readdir(dir))!=NULL  )   {if(tmp->d_type==4)//跳过系统类型文件continue;if(id==1){if(strstr(tmp->d_name,"bmp")!=NULL)   {   i++;  //计算图片数量   }} if(id==2){if(strstr(tmp->d_name,"mp3")!=NULL)   {   i++;  //计算音乐   }}   }   //根据数量 分配空间bzero(bmp,i*40);          //打开目录   if(id==1)   dir = opendir("/coolAlbum/picture");   if(id==2)   dir = opendir("/coolAlbum/music");      if(dir == NULL)   {   perror("opendir!\n");   return -1;   }      i=0;   //读文件路径   while((tmp2 = readdir(dir))!=NULL  )   {if(id==1){if(strstr(tmp2->d_name,"bmp")!=NULL){   sprintf(bmp[i++],"/coolAlbum/picture/%s",tmp2->d_name);}}if(id==2){if(strstr(tmp2->d_name,"mp3")!=NULL){   sprintf(mmp3[i++],"madplay /coolAlbum/music/%s &\n",tmp2->d_name);}}   }      return i;}//初始化显示屏int lcd_init(void){g_lcd_fd = open("/dev/fb0",O_RDWR);//打开设备g_fd_men = (unsigned long *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,g_lcd_fd,0);//建立内存映射if(g_fd_men == NULL){printf("mmap g_fd_men failed!\n");return -1;}return 0;}int lcd_uninit(void) //关闭显示屏{munmap(g_fd_men,800*480*4);}/*任意位置显示24位bmp图片unsigned long *g_fd_men:显存映射地址int x  :图片起点xint y  :图片起点y int w:图片的宽int h:图片的高const char *pathname:图片路径*/int show_shape(unsigned long *g_fd_men,int x,int y,int w,int h,const char *pathname){int bmp_fd,i,j;char bmp_buffer[w*h*3];int lcd_buffer[w*h];//打开图片bmp_fd = open(pathname,O_RDONLY);if(bmp_fd == -1){printf("open failed!\n");return -1;}//跳过54个字节头   54个是BMP 文件的信息lseek(bmp_fd,54,SEEK_SET);read(bmp_fd,bmp_buffer,sizeof(bmp_buffer));for(i=0;i<w*h;i++){lcd_buffer[i] = bmp_buffer[3*i] | bmp_buffer[3*i+1]<<8 | bmp_buffer[3*i+2]<<16; }for(i=0;i<h;i++)for(j=0;j<w;j++){*(g_fd_men+(y+i)*800+x+j) = lcd_buffer[(h-1-i)*w+j];}close(bmp_fd);return 0;}//划屏int  ts_row(void){struct tsdev *ts;struct ts_sample samp;int ret;int sub=0;//打开触摸屏ts = ts_open(DEV_NAME,0);if(ts == NULL){printf("open ts failed!\n");}//配置触摸屏,配置插件ret = ts_config(ts);if(ret == -1){printf("ts_config failed!\n");ts_close(ts);}while(1){ts_read(ts,&samp,1);printf("samp.x = %d,samp.y = %d,samp.pressure = %d\n",samp.x,samp.y,samp.pressure);if(samp.y>400&&samp.x<100&&samp.x>0&&samp.y>0){return 0;}if(samp.y>0&&samp.y<240&&samp.x>700&&samp.x<800){return 1;}if(samp.y>240 && samp.y<480 && samp.x>700 && samp.x<800){return 2;}//划屏幕的起点sub=samp.x;ts_read(ts,&samp,1);    //阻止在划屏时 触摸下一张ts_read(ts,&samp,1);if(samp.x && samp.pressure==0){if(samp.x && samp.pressure==0){printf("%d - %d = %d\n",samp.x,sub,samp.x-sub);sub =samp.x-sub ;if(sub>0)//左划{return 1;}if(sub<0)//右划{return 2;}}}}}//判断触摸的有效性struct ts_sample  ts_touch(int i){struct tsdev *ts;struct ts_sample samp;int ret;int sub=0;//打开触摸屏ts = ts_open(DEV_NAME,0);if(ts == NULL){printf("open ts failed!\n");}//配置触摸屏,配置插件ret = ts_config(ts);if(ret == -1){printf("ts_config failed!\n");ts_close(ts);}if(i==1)//判断触摸的有效性{while(1){ts_read(ts,&samp,1);if(samp.pressure==200){ts_read(ts,&samp,1);if(samp.pressure==0){ts_read(ts,&samp,1);if(samp.pressure==0){printf("ok\n");//输出触摸区域return samp;}}}}}}//弹字母   9个数字键 代表36个选择 点一个数字键 显示对应的4种选择char tancuang(int i){int j,k=4;char AA[36]={"1ABC2DEF3GHI4JKL5MNO6PQR7STU8VWX9YZ0"};char tan[40];if(i==9)k=3;if(i==0){sprintf(tan,"./setting/keyboard2/%c.bmp",AA[35]);show_shape(g_fd_men,g_y*55+30,85,51,50,tan);g_y++;if(g_y==6)g_y=0;return AA[35];}--i;for(j=0;j<k;j++){sprintf(tan,"./setting/keyboard2/%c.bmp",AA[i*4+j]);show_shape(g_fd_men,j*133 +50,150,51,50,tan);}j=ts_pw(8);sprintf(tan,"./setting/keyboard2/%c.bmp",AA[i*4+j]);show_shape(g_fd_men,g_y*55+30,85,51,50,tan);g_y++;if(g_y==6)g_y=0;return AA[i*4+j];}int  ts_pw(int function)//N多功能触摸 按键确认{struct ts_sample samp;int i=0,j=0,k=0;if(function ==1)     //数字密码判断{while(i<6){samp=ts_touch(1);printf("okkokokokoko \nsamp.x = %d,samp.y = %d,samp.pressure = %d\n",samp.x,samp.y,samp.pressure);if(samp.x>20&&samp.x<620&&samp.y<460&&samp.y>230)//输入密码的有效位置if(samp.y<340){if(samp.x<150){printf("1\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/1.bmp");num[i]='1';i++;continue;}if(samp.x<270){printf("2\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/2.bmp");num[i]='2';i++;continue;}if(samp.x<380){printf("3\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/3.bmp");num[i]='3';i++;continue;}if(samp.x<500){printf("4\n");num[i]='4';show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/4.bmp");i++;continue;}else{printf("5\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/5.bmp");num[i]='5';i++;continue;}}else{if(samp.x<150){printf("6\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/6.bmp");num[i]='6';i++;continue;}if(samp.x<270){printf("7\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/7.bmp");num[i]='7';i++;continue;}if(samp.x<380){printf("8\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/8.bmp");num[i]='8';i++;continue;}if(samp.x<500){printf("9\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/9.bmp");num[i]='9';i++;continue;}else{printf("0\n");show_shape(g_fd_men, i*102 +20 ,40,100,100,"./setting/keyboard/0.bmp");num[i]='0';i++;}}}return 1;}if(function ==2)    //登陆确认键{while(1){samp=ts_touch(1);printf("samp.x = %d,samp.y = %d,samp.pressure = %d\n",samp.x,samp.y,samp.pressure);if(samp.x>620&&samp.y>230)return 2;}}if(function ==3)//相册 与 音乐 与 返回  按键确认{while(1){samp=ts_touch(1);printf("samp.x = %d,samp.y = %d,samp.pressure = %d\n",samp.x,samp.y,samp.pressure);if(samp.x>111&&samp.y>130&&samp.x<340&&samp.y<300){return 3;}if(samp.x>470&&samp.y>130&&samp.x<700&&samp.y<300){return 4;}if(samp.y>350&&samp.x<150){return 0;}}}if(function ==4)     //测试触摸反应结果{while(1){samp=ts_touch(1);return 6;}}if(function ==6)//音乐播放按键{while(1){samp=ts_touch(1);if(samp.y>350&&samp.x<150)return 0;if(samp.y>175&&samp.x>180&&samp.x<650&&samp.y<280){if(samp.x<300)return 1;if(samp.x<420)return 2;if(samp.x<540)return 3;elsereturn 4;}}}if(function ==7)//验证码按键{while(i<6){samp=ts_touch(1);if(samp.x>20&&samp.x<620&&samp.y<460&&samp.y>230)//输入密码的有效位置if(samp.y<340){if(samp.x<150){//弹窗numm[i]=tancuang(1);i++;continue;}if(samp.x<270){numm[i]=tancuang(2);i++;continue;}if(samp.x<380){numm[i]=tancuang(3);i++;continue;}if(samp.x<500){numm[i]=tancuang(4);i++;continue;}else{numm[i]=tancuang(5);i++;continue;}}else{if(samp.x<150){numm[i]=tancuang(6);i++;continue;}if(samp.x<270){numm[i]=tancuang(7);i++;continue;}if(samp.x<380){numm[i]=tancuang(8);i++;continue;}if(samp.x<500){numm[i]=tancuang(9);i++;continue;}else{numm[i]=tancuang(0);i++;}}}}if(function ==8)//相框右侧 按键{samp=ts_touch(1);if(samp.x>20&&samp.x<500&&samp.y<230&&samp.y>125)//输入密码的有效位置{if(samp.x<150){return 0;}if(samp.x<270){return 1;}if(samp.x<380){return 2;}if(samp.x<500){return 3;}}}}void verification(void)//验证码生成与输入确认{int i,j=0;char yz[6];char v_bmp[6][40];bzero(v_bmp,6*40);char input_pasd[6];//验证码式的警告show_shape(g_fd_men,0,0,800,480,"./setting/warning2.bmp");sleep(2);show_shape(g_fd_men,0,0,800,480,"./setting/password.bmp");srand((int)time(0));//设置时间种子//生成随机的验证码//在界面上生成对应的图片while(j<6){i = 1 + (int) (2.0 * rand() / (RAND_MAX + 1.0));if(i==1){i = 0 + (int) (9.0 * rand() / (RAND_MAX + 1.0));yz[j]='0'+i;}if(i==2){i = 0 + (int) (25.0 * rand() / (RAND_MAX + 1.0));yz[j]='A'+i;}sprintf(v_bmp[j],"./setting/keyboard2/%c.bmp",yz[j]);show_shape(g_fd_men, j*55+30, 30 ,51,50,v_bmp[j]);j++;}printf("%s\n",yz);i=0;ts_pw(7);stpcpy(input_pasd,numm);  //接收触摸屏密码if( ts_pw(2)==2 && (strcmp(yz,input_pasd)==0))//点击go,判断密码正确{usr_password();}elseverification();}int usr_password(void)//开机密码输入{int fd;char ch;char usrpasd[7];char input_pasd[6];int i=0;//打开文件fd = open(USR_PW,O_RDONLY);if(fd == -1){printf("open ps file failed!\n");return -1;}read(fd,usrpasd,6);usrpasd[6]='\0';//若是不赋值零的话 他可能会以为字符没读完,而越界了printf("usrpd = %s\n",usrpasd);i=0;while(1){//输入密码页面show_shape(g_fd_men,0,0,800,480,"./setting/password.bmp");printf("please input passwd!\n");ts_pw(1);stpcpy(input_pasd,num);  //接收触摸屏密码printf("%s\n%s\n",usrpasd,input_pasd);if( ts_pw(2)==2 && strcmp(usrpasd,input_pasd)==0 )//点击go,判断密码正确{sleep(1);//登陆成功printf("compare correct!\n");//进入 电子相册 和 MP3 选择页面picture_or_music();break;}i++;if(i==3){//第三次输入错误,死机  或者 开启验证码输入printf("you haven't no change input!\n");//进入验证码模式verification();}//输入错误警告show_shape(g_fd_men,0,0,800,480,"./setting/warning.bmp");sleep(1);}close(fd);return 0;}void picture_or_music(void);void picture(void)//电子相册 页面{int i,j;//初始化链表double_list head_list = init_list();double_list new;//读取路径导入到链表i=dir(1);if(i==-1){printf("picture read  dir  fail\n",i);}for(i-=1;i>=0;i--)//插入链表{new = init_list();stpcpy(new->bmpp,bmp[i]);printf("%s\n",new->bmpp);insert_node(new,head_list);}if(g_x==1)//相册介绍使用教程{show_shape(g_fd_men,0,0,800,480,"/coolAlbum/setting/picture.bmp");sleep(1);}double_list p =head_list->next;show_shape(g_fd_men,0,0,800,480,p->bmpp);while(1){j=ts_row();//判断滑动状态g_x=0;if(j==1){p = p->prev;if(p==head_list)//判断是不是头节点 因为头节点没有数据p=p->prev;show_shape(g_fd_men,0,0,800,480,p->bmpp);}if(j==2){p = p->next;if(p==head_list)p=p->next;show_shape(g_fd_men,0,0,800,480,p->bmpp);}if(j==0){picture_or_music();}}}void mp3(void)//音乐播放页面{int i,j,x,z=0;//初始化链表double_list head_list = init_list();double_list new;//读取路径导入到链表i=dir(2);if(i==-1){printf("picture read  dir  fail\n",i);}printf("i=%d\n",i);for(i-=1;i>=0;i--){new = init_list();stpcpy(new->bmpp,mmp3[i]);printf("------%s----\n",new->bmpp);insert_node(new,head_list);}show_shape(g_fd_men,0,0,800,480,"/coolAlbum/setting/music.bmp");double_list p =head_list;while(1){j=ts_pw(6);if(j==1){//上一首system("killall -KILL madplay\n");p = p->prev;if(p==head_list)p=p->prev;system(p->bmpp); }if(j==2){p = p->next;system("killall -STOP madplay&\n");//停止音乐z=1;}if(j==3){//system(p->bmpp);  //启动音乐if(z==0)system("madplay /coolAlbum/music/sd.mp3&\n");  //启动音乐if(z==1)system("killall -CONT madplay&\n");//继续播放}if(j==4){//下一首system("killall -KILL madplay\n");p = p->next;if(p==head_list)p=p->next;printf("   %s\n  ",p->bmpp);system(p->bmpp); }if(j==0){picture_or_music();}}}void picture_or_music(void)//触摸选择  电子相册 MP3 返回{int i;//加载登陆后的图片 带返回show_shape(g_fd_men, 0,0,800,480,"./setting/picture_or_mp3.bmp");i=ts_pw(3);//触摸选择区域  电子相册 MP3  返回if(3== i){picture();}if(4== i)//进入MP3{mp3();}if(0== i)//返回到输入页面{usr_password();}}int main(void){int i=10;lcd_init();//屏幕初始化show_shape(g_fd_men,0,0,800,480,"./setting/logo.bmp");//开启画面system("madplay /coolAlbum/music/sd.mp3&\n"); //开机音乐sleep(3);usr_password();//密码输入lcd_uninit();return 0;}


0 0
原创粉丝点击