近年來(lái),由于ARM(Advanced RISC Machines)在性能、功耗、成本和體積上的優(yōu)勢,使得它在嵌入式系統中的發(fā)展如日中天,它在工業(yè)控制、航空航天、軍事領(lǐng)域、消費電子、智能家電和視頻監控等方面都發(fā)揮了重大的作用。很多人都迫切地想學(xué)習ARM,以筆者的經(jīng)驗,從最基本的LED控制學(xué)起,是一個(gè)不錯的選擇。 如果不熟悉Linux,可能對QtE的概念知之甚少,它是挪威Trolltech公司為各種系統設計的圖形用戶(hù)界面工具包,采用c++語(yǔ)言編程。QtE的優(yōu)點(diǎn)有:跨平臺,可以方便的連接數據庫,可以將程序與Java集成等。其實(shí),QtE在一些高端的移動(dòng)手持設備中早已深入人心,Troll—tech公司在QtE的基礎上開(kāi)發(fā)了一個(gè)應用環(huán)境Qtopia,目前已有很多公司采用Qtopia來(lái)開(kāi)發(fā)他們的主流PDA。當然,Qt也有它的缺點(diǎn),既不能提供IDE(集成開(kāi)發(fā)環(huán)境),但這個(gè)缺點(diǎn)在強大的Linux下顯得微不足道。使用gcc/g++,加上Qt的開(kāi)發(fā)工具:Qt Designer,tmake/qmake,UIC等,開(kāi)發(fā)可視化程序將變得十分容易。 要學(xué)習ARM,選擇一款好的開(kāi)發(fā)板是必不可少的。SBC一2410X是廣州友善之臂公司設計的一款基于A(yíng)RM9的開(kāi)發(fā)板,操作系統是韓國的mizi-linux。SBC-2410X不同于uClinux,它的接口豐富,且支持MMU、QtE2.3.7,同時(shí)提供了控制LED的命令行方式。 1 系統需求 ◇完全安裝RedHat9.0。 ◇在Linux下建立QtE編譯環(huán)境。 ◇開(kāi)發(fā)板上已經(jīng)加載LED設備驅動(dòng)程序。 注意:你所建立的QtE版本必須與開(kāi)發(fā)板所支持的版本一致。 2 程序設計 在Linux下,用系統自帶的Qt Designer來(lái)編寫(xiě)程序。Qt Designer是一個(gè)優(yōu)秀的可視化開(kāi)發(fā)工具,用它來(lái)設計十分容易。它的界面類(lèi)似于Delphi,但使用C++語(yǔ)言編寫(xiě)應用程序。Qt程序設計里的一個(gè)亮點(diǎn)就是SignaI-_Slot機制,它有點(diǎn)類(lèi)似于VC++里的消息機制。當一個(gè)組件發(fā)出Signal時(shí),其他一個(gè)組件或多個(gè)組件可以通過(guò)Slot接收發(fā)來(lái)的SignaI,組件本身也可以接收自己的Signal,這樣處理一個(gè)事件將變得非常容易。Qt Designer的優(yōu)點(diǎn)不僅在于它可以十分方便的設計圖形用戶(hù)界面,還表現在可以用連接工具很容易的把Signals和Slots連接起來(lái)。用戶(hù)自己設計的程序添加在**.ui.h中。 打開(kāi)Qt Deslgner,選擇File/new C++Project,命名為led.pro并保存。接著(zhù)選擇File/new-Dialog,并在此設計自己的用戶(hù)界面。最后選擇File/new C++Main—File,系統自動(dòng)生成一個(gè)main.cpp文件。圖形用戶(hù)界面如圖1所示,Initlalize按鈕主要完成LED設備的打開(kāi),定時(shí)器的關(guān)閉和其他一些初始化工作;Begim按鈕則針對LED Display Mode的開(kāi)始;Exit按鈕為退出應用程序。左面的組合框包括4個(gè)RadioButton,對應4個(gè)LED的亮或滅;右面的組合框包括6個(gè)RadioButton(對應不同的閃爍模式和閃爍快慢)和1個(gè)LCDNumber(用來(lái)顯示閃爍的時(shí)間間隔)。本程序建立的Signal—S1ot連接有許多,下面對幾個(gè)重要的連接和函數進(jìn)行說(shuō)明。 (1)connect(initPushButton.SIGNAL(clicked()),this.SLOT(initial())) 當Initialize按鈕按下時(shí),LedForm對話(huà)框接收此信號,并執行initial()函數。Linux操作系統把所有的設備都看成文件,因此對設備的操作控制可以通過(guò)open()、ioctl()等函數實(shí)現。在initial()函數中就是調用了open()函數來(lái)打開(kāi)LED設備的。 (2)connect(okPushButton,SIGNAL(clicked()),this,SLOT(modeSel())) 當Begin按鈕按下時(shí),LedForm對話(huà)框接收此信號,并執行modeSel()函數。在modeSel()函數中開(kāi)啟定時(shí)器,并創(chuàng )建另外一個(gè)連接用來(lái)循環(huán)顯示LED。在命令行方式中,LED的循環(huán)顯示要用到死循環(huán),并用鍵盤(pán)中斷來(lái)控制循環(huán);而在Qt或其他可視化語(yǔ)言中,則要用到定時(shí)器來(lái)控制循環(huán)。 (3)函數open() 在中聲明,含義為打開(kāi)設備文件。打開(kāi)成功返回0;失敗返回一1。 (4)函數ioctl() 在中聲明,控制I/O端口。例如: Int fd=open(”/dev/leds”,0); ioctl(fd,0,3); //讓LED4滅 (5)函數select() 在中聲明,含義為經(jīng)過(guò)多長(cháng)時(shí)間訪(fǎng)問(wèn)一次設備。 3 程序移植與運行 要想使程序運行在開(kāi)發(fā)板的Qtopia中,則必須在建立的QtE環(huán)境下編譯,并設置好環(huán)境變量。終端進(jìn)入所建立的QtE目錄后,環(huán)境變量或運行環(huán)境變量和腳本設置如下: export QTDIR=$PWD/qt export QPEDlR=$PWD/qtopia export TMAKEDIR=$PWD/tmake export TMAKEPATH=$TMAKEDIR/lib/qws/linux-armg++ export PATH=$QTDIR/bin:$QPEDIR/bin:$TMAKEDIR/ bin:$PATH 值得注意的一點(diǎn)是:用Linux自帶的Qt Designer創(chuàng )建的工程文件只適用于qmake,而筆者建立的QtE環(huán)境只能用tmake來(lái)生成makefile,因此需要修改led.pro文件,讓它適用于tmake,修改如下: TEMPLATE =app CoNFIG +=qtopia warn_on release SoURCES +=main.epp INTERFACES =led.ui TARGET =led 以上的工作做完后,就可以編譯了。編譯成功后生成可執行的二進(jìn)制文件led,然而要使程序運行在開(kāi)發(fā)板上的qtopia桌面上,還需要一個(gè)桌面文件led.desktop和自定義的一個(gè)圖標led.png。桌面文件如下: [Desktop Entry] Comment=a LED Control Program Exee=led Icon=led Type=Application Name=LED Control 然后,把led復制到SBC-2410X下/opt/qtopia/bin目錄下,led.png復制到/opt/qtopia/pics目錄下,led.desktop復制到/0pt/qtopia/apps/Applications目錄下。最后,用ehmod a+X led改變文件led的權限,重新啟動(dòng)系統,便可看到led.png的圖標顯示在qtopia桌面上,點(diǎn)擊此圖標就可運行程序了。 4 部分源程序及注釋 由于源程序代碼比較長(cháng),這里就不全部列出了,僅給出重要部分的代碼及注釋?zhuān)怨┳x者參考。 (1) 程序的初始化 int fd: //LED設備文件句柄 int type=1; //默認方式為計數器 double period=0.2; //默認時(shí)間間隔 QTimer*t=new QTimer(Q″timer″);//創(chuàng )建定時(shí)器 void LedForm::initial(){ fd=open(″/dev/leds″,0); //打開(kāi)LED設備 //其他一些初始化語(yǔ)句 一>stop(); //關(guān)閉定時(shí)器 ~ (2) LED顯示方式的設置 void LedForm::push-leds(void){ static unsigned step; unsigned led—bitmap; inti; switch(type){ case 0: //方式0:跑馬燈 if(step>=14){step=0;} if(step255){step=0;) Ied_bitmap=step! break; case 2: //方式2:停止 led_bitmap=0: break; step十十; for(i=0;i>=1; } } (3) LED設備的讀取及調用LED顯示程序 void LedForm::ledDisplay(){ fd_set rds; struct timeval step; FD_ZERO(%26;amp;rds); step.tv_sec=period; step.tv_usec=(pefiod—step.W_sec)*1000000L; select(fd,%26;amp;rds,NULL,NULL,%26;amp;step); push_leds(); } (4)循環(huán)顯示的實(shí)現 void LedForm::modeSel(){ t-->start(O);//啟動(dòng)定時(shí)器,并立即發(fā)出Signal- timeout() connect(t,SIGNAL(timeout()),this.SLOT(1edDisplay())); } 結 語(yǔ) 隨著(zhù)通信行業(yè)的迅猛發(fā)展,移動(dòng)手持設備必將成為人們工作、學(xué)習和生活的主流,用Qt設計移動(dòng)手持設備的GUI有著(zhù)得天獨厚的優(yōu)勢。目前,Qt應用于全世界上百個(gè)軟件開(kāi)發(fā)項目中。在我國,Qt的發(fā)展也有星星之火可以燎原之勢。本文通過(guò)一個(gè)最基礎的小程序向讀者演示了怎樣使用Qt開(kāi)發(fā)應用程序,以及怎樣建立Qt與ARM的聯(lián)系,希望對讀者學(xué)習ARM和Qt起到一定的幫助作用。 |