《智慧家居》培訓第三天------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張音樂介面圖,其餘兩張如下: