1. 程式人生 > >《智慧家居》培訓第三天------2019-01-07

《智慧家居》培訓第三天------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座標,然後把這個記錄下來的資訊是儲存到這個“觸控式螢幕”檔案中。

  ③那麼觸控位置就確定了,這個時候我們就只需要讀取出這個檔案中儲存的位置座標,就可以得到使用者觸控的位置,根據此位置就可以實現自己想要實現的功能。

 

  ④舉個例子:我們希望當用戶點選某個區域時,播放一首歌,那麼相應的邏輯就是→使用者觸控式螢幕幕→觸控位置的座標被儲存到“觸控式螢幕”檔案中→從該檔案中讀取使用者觸控的位置→判斷該位置是不是播放音樂的位置→如果是就播放音樂

  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 [[email protected] /]# tar zxvf tslib.tar.gz 
 5 3)上傳profile配置檔案到 /etc目錄下,替換原來的profile
 6 cd /etc ----- 進入該目錄
 7 rx profile ----上傳檔案
 8 4)重啟開發板---reboot
 9 5)進入tslib/bin ---- 
10  [[email protected] /]# cd tslib/
11 [[email protected] /tslib]# ls
12 bin      etc      include  lib
13 [[email protected] /tslib]# cd bin/
14 [[email protected] bin]# ls
15 ts_calibrate  ts_harvest    ts_print      ts_print_raw  ts_test
16 [[email protected] 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張音樂介面圖,其餘兩張如下: