《智能家居》培训第三天------2019-01-07

目录:

  一)如何把3字节数据转换为4字节数据

  二)动态界面→触摸屏的实现

  三)多个源文件编译以及链接库

  四)cannot open shared object file的解决办法

  五)界面转换函数的封装

  六)音乐界面的实现

  七)所想

  八)总结

一)如何把3字节数据转换为4字节数据

  1)我自己写的方法无法完美显示,虽然可以显示图片信息,但是整张图片都被染上了一层厚厚的深蓝色,代码如下,这段代码我还没有重新看看是哪里出错了

 1     j=0 2     for(i=0;i<800*480;i++)
 3     {
 4         bmp_buf[j]<<8;
 5         a=bmp_buf[j]+bmp_buf[j+1];
 6         a<<8;
 7         a+=bmp_buf[j+2];
 8         a>>8;
 9         bmp_buf1[i]=a;
10         j+=3;
11     }

  2)老师讲的方法如下,也是通过位操作实现,而且看起来很简洁明了,不像我那个一大串还不成功

1     int lcd_buf[800*480];          //int类型,4字节
2     char bmp_buf[800*480*3]        //char类型,1字节
3     int i;
4     for(i=0;i<800*480;i++)
5     {
6         lcd_buf[i] = 0x00 <<24 | bmp_buf[3*i+2]<<16 | bmp_buf[3*i+1] <<8 | bmp_buf[3*i+0];
7      //0x00ff0000; //argb 8 }

  知识:把两个字节前后拼接在一起,使用位运算符“|”,而不是用“+”,比如0xff00 | 0x00ff = 0xffff

二)动态界面→触摸屏的实现

  1)动态界面

  动态界面就是可以和用户实现交互的界面,比如触摸,通过触摸屏幕使界面发生某种变化

  2)触摸屏的原理

  对于这块我目前还是没有真正理解,以下是我根据老师笔记以及培训时所讲得到的理解,如果大家有其他理解可以分享一下的话就谢谢啦

  ①“触摸屏”是一种设备文件,意思就是说有这么一个文件,这个文件上的内容专门用于描述用户对屏幕触摸的操作。

  ②当用户点击触摸屏时,linux系统就会记录下用户的操作,比如记录下所触摸位置的xy坐标,然后把这个记录下来的信息是保存到这个“触摸屏”文件中。

  ③那么触摸位置就确定了,这个时候我们就只需要读取出这个文件中保存的位置坐标,就可以得到用户触摸的位置,根据此位置就可以实现自己想要实现的功能。

扫描二维码关注公众号,回复: 4835023 查看本文章

  ④举个例子:我们希望当用户点击某个区域时,播放一首歌,那么相应的逻辑就是→用户触摸屏幕→触摸位置的坐标被保存到“触摸屏”文件中→从该文件中读取用户触摸的位置→判断该位置是不是播放音乐的位置→如果是就播放音乐

  3)检测触摸屏操作的实现

  ①对于触摸屏来说,linux系统把它当做一种输入设备,在目录“/usr/include/linux”下的input.h文件中描述了触摸屏操作。

 1 /*
 2  * The event structure itself
 3  */
 4 
 5 struct input_event {
 6     struct timeval time; //事件发生的时间
 7     __u16 type; //事件发生的类型:触摸屏
 8     __u16 code; //x轴 或者 Y轴
 9     __s32 value; //x的坐标或者y的坐标
10 };

  ②老师已经把检测触摸屏操作封装成了一个库,我们只需要直接调用函数get_x_y(&x,&y);就可以得到x,y的坐标了,老师在上课的时候也有讲解这个函数怎么写,但是由于时间问题就没有细讲,这部分就直接给个函数接口,因此此处不做太多详细描述。(给自己的话:可以看当日笔记了解更多)

三)多个源文件编译及链接库

  1)多个源文件编译,源文件之间用空格隔开

  比如触摸操作函数被封装为单个源文件ts.c,主程序在main.c中,现在要把这两个文件同时编译,生成一个传入开发板的文件main,编译语法为:arm-linux-gcc main.c ts.c -o main

  2)链接库

  小知识:动态库------未作深入学习,只知道其中的代码是不可见的,是linux下后缀为.so的文件。

  用上述语句编译会产生错误,原因在于:触摸函数所在的源文件ts.c里的某些函数,需要使用到一个动态库里的内容,这个动态库才是最主要的,检测触摸的操作都是靠这个库来实现的,正确的编译语法如下:

  arm-linux-gcc main.c ts.c -o main -L ./tslib/ -lts

  -L ----- 表示要链接动态库 

  ./tslib/  ----- 动态库所在的目录

  -lts ----- 具体的动态库

四)cannot open shared object file的解决办法

  错误提示:./aa: error while loading shared libraries: libts-0.0.so.0: cannot open shared object file: No such file or directory

  上述错误是在执行编译生成的main文件时产生的,原因已经忘记,老师发送了一个压缩包和一个文件给我们,让我们根据以下进行操作,然后就解决问题了

 1 1)上传tslib.tar.gz
 2 rx tslib.tar.gz
 3 2)在开发板上解压tslib.tar.gz到根目录(/)
 4 [root@GEC210 /]# tar zxvf tslib.tar.gz 
 5 3)上传profile配置文件到 /etc目录下,替换原来的profile
 6 cd /etc ----- 进入该目录
 7 rx profile ----上传文件
 8 4)重启开发板---reboot
 9 5)进入tslib/bin ---- 
10  [root@GEC210 /]# cd tslib/
11 [root@GEC210 /tslib]# ls
12 bin      etc      include  lib
13 [root@GEC210 /tslib]# cd bin/
14 [root@GEC210 bin]# ls
15 ts_calibrate  ts_harvest    ts_print      ts_print_raw  ts_test
16 [root@GEC210 bin]# ./ts_calibrate  ----进行触摸屏测试
17 校准:左上角  右上角 右下角
18       左下角   中心 ----依次点击,完成OK

  触摸屏测试失败了,手上的触摸屏有问题,无法检测到触摸操作,第二天换了个板子就可以了,但换的那个板子其实触摸也还是有点问题。

五)界面转换函数的封装

  1)为什么要封装函数

  我的理解就是为了让main.c源文件看起来更加简洁,功能分区更加明显,为以后进行代码修改提供了方便。

  2)如何封装界面转换函数

  把昨天界面显示的代码全部封装到一个函数里面,再加个参数char *pathname,表示要显示的图片路径,在main函数里直接调用该函数就可以了(如:show_screen("my_screen.bmp")显示my_screen.bmp这张图)

int show_screen(char* pathname)
{
    //[1]打开屏文件和图片--bmp
    int lcd_buf[800*480];
    char bmp_buf[800*480*3];
    int i,fd,fd_bmp;
    fd = open("/dev/fb0",O_WRONLY);
    if(fd == -1)
    {
        printf("open lcd error\n");
        return -1;
    }
    fd_bmp = open(pathname,O_RDONLY); //与可执行程序同一目录
    if(fd_bmp == -1)
    {
        printf("open bmp error\n");
        return -1;
    }  
    //偏移掉图片的文件信息---54B --- lseek
    lseek(fd_bmp,54,SEEK_SET);    
    //[2] 读取bmp图片的数据存放在数组中 char bmp[800*480*3]
    read(fd_bmp,bmp_buf,800*480*3);    
    //[3] 图片3字节数据转换屏对应4字节的数据
    for(i=0;i<800*480;i++)
    {
        lcd_buf[i]=0x00<<24|bmp_buf[3*i+2]<<16|bmp_buf[3*i+1]<<8|bmp_buf[3*i+0];
    }
    //[4] 把图片的坐标系转屏的坐标系统    
    //[5] 把数据写入到屏中
    write(fd,lcd_buf,480*800*4);    
    //[6] 关闭文件
    close(fd);
    close(fd_bmp);
}

六)音乐界面的实现

  1)今日任务:实现功能------>进入主界面→用户点击“音乐”→进入音乐界面→该界面有以下功能:播放、暂停\继续、停止、上一首、下一首、返回主界面

  2)实现逻辑

  3)音乐界面与对应触摸位置

  4)代码(代码包含第四天学习的内容,整个框架是今天也就是第三天培训学的)

 1 int main()
 2 {
 3     int x,y;
 4     int pause_flag=1;  //用于判断是暂停歌曲还是继续歌曲
 5     //打开触摸屏
 6     my_tsopen();
 7     while(1)
 8     {
 9         //一级界面----主界面
10         show_screen("./my_screen.bmp");
11         //等待用户点击,获取点击的x,y的坐标
12         get_x_y(&x,&y);
13         //若点击“音乐”则进入二级界面----音乐
14         if((x>=240&&x<=340)&&(y>=200&&y<=260))
15         {    
16             //显示音乐界面
17             show_screen("./music_screen2.bmp");        
18             while(1)
19             {
20                 //等待用户点击,获取x,y的坐标
21                 get_x_y(&x,&y);
22                 if((x>=25&&x<=125)&&(y>=400&&y<=450))//点击播放
23                 {
24                     music_play();
25                 }else if((x>=160&&x<=260)&&(y>=400&&y<=450)){     //点击暂停
26                     switch(pause_flag)
27                     {
28                         case 1:music_pause();pause_flag++;break;    //第一次点击暂停为暂停音乐
29                         case 2:music_continue();pause_flag--;break; //第二次点击暂停为继续音乐
30                     }
31                 }else if((x>=300&&x<=400)&&(y>=400&&y<=450)){  //点击停止
32                     music_stop();
33                 }else if((x>=440&&x<=560)&&(y>=400&&y<=450)){  //点击上一首
34                     music_previous();
35                 }else if((x>=620&&x<=740)&&(y>=400&&y<=450)){  //点击下一首
36                     music_next();
37                 }else if((x>=690&&x<=780)&&(y>=50&&y<=100)){    //点击返回
38                     music_back();
39                     break;
40                 }
41             }
42         }
43     }
44 }

  5)第四天培训实现播放等功能,今天就只是制作好音乐界面以及写好一个框架就行。

七)所想

  1)今天没什么特别的想法,就只是因为触摸屏感应不了触摸而有一点伤心与焦急,晚上把框架码好了却无法在板子上试一下,希望自己写的代码没有问题。

八)总结

  1)学习了如何通过位操作实现数据类型转换

  2)封装的思想

  3)写了个音乐框架,制作了3张音乐界面图,其余两张如下:

猜你喜欢

转载自www.cnblogs.com/lzemian-n/p/10236953.html