<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于μClinux的觸摸屏設(shè)計(jì)與關(guān)鍵技術(shù)分析

          基于μClinux的觸摸屏設(shè)計(jì)與關(guān)鍵技術(shù)分析

          作者: 時(shí)間:2011-09-27 來源:網(wǎng)絡(luò) 收藏
          本文介紹了當(dāng)前比較流行的開放源代碼的嵌入式操作系統(tǒng)下驅(qū)動程序的一般結(jié)構(gòu),以及控制器和Motorola DragonBallMCVZ328 CPU的連接。

          在此基礎(chǔ)上,詳細(xì)講述了驅(qū)動程序設(shè)計(jì)的一些關(guān)鍵技術(shù),如阻塞型I/O操作、任務(wù)隊(duì)列以及系統(tǒng)定時(shí)器的應(yīng)用等,解決了采樣數(shù)量控制問題,具有較好的移植性。
            

          1引言

          1.1背景介紹

          隨著信息技術(shù)的發(fā)展,嵌入式系統(tǒng)越來越廣泛地應(yīng)用到航空航天、通訊設(shè)備、工業(yè)控制等領(lǐng)域。由于尺寸的限制,代替鍵盤和鼠標(biāo)成為嵌入式系統(tǒng)首選的輸入工具。同時(shí)嵌入式系統(tǒng)也逐漸摒棄了傳統(tǒng)的循環(huán)控制模式,而是引入操作系統(tǒng)完成進(jìn)程間切換和任務(wù)調(diào)度。就是一種優(yōu)秀的開放源代碼的嵌入式操作系統(tǒng)。它經(jīng)過各方面的小型化改造,形成了一個(gè)高度優(yōu)化的、代碼緊湊的嵌入式Linux,雖然它的體積很小,仍然保留了Linux的大多數(shù)優(yōu)點(diǎn):穩(wěn)定良好的移植性、優(yōu)秀的網(wǎng)絡(luò)功能、完備的對各種文件系統(tǒng)的支持以及標(biāo)準(zhǔn)豐富的API。比較起其它幾種應(yīng)用較多的嵌入式操作系統(tǒng),像vxworks、winCE等,它較為低廉的價(jià)格以及方便的用戶程序開發(fā),無疑是其巨大的優(yōu)勢。用戶可以方便地從互聯(lián)網(wǎng)上找到最新內(nèi)核版本、編譯器以及其它必需的軟件環(huán)境,這也促使眾多愛好者加盟。

            1.2研究現(xiàn)狀

            由于觸摸屏使用得越來越廣泛,所以相應(yīng)的研究與工程實(shí)踐比較多。在現(xiàn)有的工作中,已有很多工程師對觸摸屏控制器ADS7846與StrongARM平臺的硬件連接以及在WinCE操作系統(tǒng)中軟件驅(qū)動程序開發(fā)進(jìn)行了研究,并對改進(jìn)觸摸屏控制器硬件精度上做了一定探索。而本文的主要貢獻(xiàn)在于詳細(xì)描述了在μClinux這一嵌入式操作系統(tǒng)中觸摸屏驅(qū)動程序硬件及軟件設(shè)計(jì)。實(shí)踐證明,這一設(shè)計(jì)具有比較高的精度、穩(wěn)定性和開放性,而且跨平臺性也較好,因此必將給嵌入式設(shè)備提供更多選擇。

            2硬件設(shè)計(jì)

            本設(shè)計(jì)中硬件平臺微處理器選用Motorola公司的MC68VZ328,它是一款M68k體系的32位低功耗微處理器,采用SoC技術(shù)設(shè)計(jì),具有典型的嵌入式微處理器的特征;觸摸屏選用TI(原為Burr-Brown公司的產(chǎn)品,由于該公司已被TI公司收購,所以下文均用TI公司)公司的ADS7843。在本設(shè)計(jì)中,CPU與觸摸屏以主從方式工作,觸摸屏工作于從設(shè)備(slave)狀態(tài)。本設(shè)計(jì)中硬件電路不同于傳統(tǒng)設(shè)計(jì),而是充分利用了ADS7843中的BUSY信號線,如圖1所示。

          ADS7843是一款四線電阻式觸摸屏控制芯片,它主要完成兩件事情:其一,是完成電極電壓的切換;其二,是采集接觸點(diǎn)處的電壓值。它由兩層透明的阻性導(dǎo)體層組成,在導(dǎo)體層中間充滿了用粘性絕緣液體材料做成的隔離層和由導(dǎo)電性能極好的材料構(gòu)成的電極。

            觸摸屏工作時(shí),上下導(dǎo)體層相當(dāng)于電阻網(wǎng)絡(luò),如圖2所示。當(dāng)某一層電極加上電壓時(shí),會在該網(wǎng)絡(luò)上形成電壓梯度。若有外力使得上下兩層在某一點(diǎn)接觸,則在電極未加電壓的另一層可以測得接觸點(diǎn)處的電壓,從而知道接觸點(diǎn)處的坐標(biāo)。比如,若在頂層的電極(X+、X-)上加上電壓,則在頂層導(dǎo)體層上形成電壓梯度;當(dāng)有外力使得上下兩層在某一點(diǎn)接觸,在底層就可以測得接觸點(diǎn)處的電壓,再根據(jù)該電壓與電極(X+)之間的距離關(guān)系,知道該處的X坐標(biāo)。然后,將電壓切換到底層電極(Y+、Y-)上,并在頂層測量接觸點(diǎn)處的電壓,從而知道Y坐標(biāo)。對電壓在橫向和縱向?qū)w層之間的切換以及A/D轉(zhuǎn)換,需要先通過串行外設(shè)接口(SPI)往ADS7843發(fā)送控制字,轉(zhuǎn)換完成后再通過SPI讀出電壓轉(zhuǎn)換值。

            3軟件設(shè)計(jì)

            3.1μClinux下驅(qū)動程序的特點(diǎn)

            μClinux繼承了Linux的設(shè)備管理方法,將所有的設(shè)備看做具體的文件,通過文件系統(tǒng)層對設(shè)備進(jìn)行訪問。所以在Clinux的框架結(jié)構(gòu)中,和設(shè)備相關(guān)的處理可以分為兩個(gè)層次——文件系統(tǒng)層和設(shè)備驅(qū)動層。設(shè)備驅(qū)動層屏蔽具體設(shè)備的細(xì)節(jié),文件系統(tǒng)層則向用戶提供一組統(tǒng)一的規(guī)范的用戶接口。這種設(shè)備管理方法可以很好地做到“與設(shè)備無關(guān)性”,使Clinux可以根據(jù)硬件外設(shè)的發(fā)展進(jìn)行方便的擴(kuò)展,比如要實(shí)現(xiàn)一個(gè)設(shè)備驅(qū)動程序,只要根據(jù)具體的硬件特性向文件系統(tǒng)提供一組訪問接口即可。

            μClinux中的設(shè)備可以分為3類:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備。其中字符設(shè)備沒有緩沖區(qū),數(shù)據(jù)的處理是以字節(jié)為單位按順序進(jìn)行的,它不支持隨機(jī)讀寫,觸摸屏即屬于字符設(shè)備的一種。

            驅(qū)動程序在內(nèi)核中裝載的方式有兩種:一種是直接編譯進(jìn)內(nèi)核,在系統(tǒng)初始化的時(shí)候就對設(shè)備進(jìn)行注冊;一種是模塊化加載的方法,將驅(qū)動程序編譯成目標(biāo)文件(*.o),需要添加設(shè)備時(shí),使用insmod命令向系統(tǒng)注冊,停止使用時(shí),用rmmod命令卸載。對于觸摸屏這種基本的輸入工具,建議采取直接編譯進(jìn)內(nèi)核的方式,這樣系統(tǒng)一啟動就可以使用了。

            向內(nèi)核注冊一個(gè)字符設(shè)備的函數(shù)為:externintregister_chrdev(unsignedintmajor,constchar*name, structfile_operations*fops);內(nèi)核用主設(shè)備號和次設(shè)備號惟一地標(biāo)識一個(gè)設(shè)備。參數(shù)major對應(yīng)所請求的主設(shè)備號,name對應(yīng)設(shè)備的名字,fops是一個(gè)指向file_operations結(jié)構(gòu)的指針,它是Clinux下編寫驅(qū)動程序用到的一個(gè)關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),它提供了應(yīng)用空間與驅(qū)動程序的調(diào)用接口。這個(gè)數(shù)據(jù)結(jié)構(gòu)的每一項(xiàng)都指向驅(qū)動程序完成的一個(gè)功能。

            在2.4版本內(nèi)核中對該結(jié)構(gòu)采取標(biāo)記結(jié)構(gòu)初始化語法(TaggedStructureInitializationSyntax),與2.0內(nèi)核比較,這種語法可移植性更好,程序的可讀性和代碼的緊湊性都比較好。以觸摸屏為例:

            static struct file_operations ts_fops={

            owner:THIS_MODULE,

            read:ts_read, //讀數(shù)據(jù)操作

            poll:ts_poll, //非阻塞操作

            ioctl:ts_ioctl, //I/O控制操作

            open:ts_open, //打開設(shè)備

            release:ts_release, //釋放設(shè)備

            fasync:ts_fasync, //異步觸發(fā)}

            完整的結(jié)構(gòu)還包括llseek、readdir等函數(shù)指針,只是由于在本程序中沒有用到,所以省略不寫,內(nèi)核把它們默認(rèn)為空(NULL)。

            3.2觸摸屏驅(qū)動程序的流程及關(guān)鍵函數(shù)

            在本設(shè)計(jì)中,我們使用μClinux2.4內(nèi)核。驅(qū)動程序主要設(shè)計(jì)思想是:驅(qū)動程序在初始化結(jié)束后,進(jìn)入空閑狀態(tài),等待中斷的到來。一旦筆中斷(pen_irq)發(fā)生,則進(jìn)入中斷處理程序,進(jìn)行數(shù)據(jù)采樣、轉(zhuǎn)換和傳輸,同時(shí),程序?qū)Ω鞣N不同的情況進(jìn)行鑒別和異常處理。

            觸摸屏軟件流程如圖3所示。在驅(qū)動程序中設(shè)定了觸摸屏所處的7個(gè)不同狀態(tài),分別用從-1到5的數(shù)字表征,這7個(gè)狀態(tài)構(gòu)成了一個(gè)觸摸屏狀態(tài)機(jī),系統(tǒng)根據(jù)當(dāng)前狀態(tài)做出下一步的處理,如表1所示。整個(gè)軟件設(shè)計(jì)根據(jù)功能可以劃分為5個(gè)部分,分別是初始化、設(shè)備打開、讀操作、中斷處理以及I/O控制,下面具體介紹每一部分。

            

          3.2.1驅(qū)動程序初始化

            在mc68328digi_init()中向內(nèi)核注冊設(shè)備驅(qū)動函數(shù):err=misc_register(mc68328_digi),在init_ts_settings()中設(shè)定觸摸屏的當(dāng)前參數(shù):內(nèi)核版本號、筆移動判別閾值、采樣時(shí)間、消除抖動開關(guān)、消除抖動時(shí)間等參數(shù),這些均由用戶根據(jù)自己的液晶屏以及精度要求來定制,也可以在應(yīng)用程序中用I/O控制函數(shù)ioctl()來設(shè)定,本文將在參數(shù)分析中具體分析這些參數(shù)的意義。

            3.2.2打開設(shè)備

            在ts_open()函數(shù)中,驅(qū)動程序向內(nèi)核注冊中斷。中斷也可以在系統(tǒng)初始化的時(shí)候向內(nèi)核注冊,但是一般不建議這樣做,因?yàn)樵诩虞d的設(shè)備比較多時(shí),這樣做有可能造成中斷的沖突。打開一個(gè)設(shè)備,才讓該設(shè)備占用中斷,是一個(gè)較好的策略。向內(nèi)核注冊中斷處理程序主要實(shí)現(xiàn)兩個(gè)功能,一是注冊中斷號,二是注冊中斷處理函數(shù)。

            本程序中,向內(nèi)核注冊了兩個(gè)中斷處理程序,分別是:

            request_irq(PEN_IRQ_NUM, handle_pen_irq,IRQ_FLG_STD,

            “touch_screen”,NULL)和request_ irq(SPI_IRQ_NUM,handle_spi_irq, IRQ_FLG_STD,“spi_irq”,NULL);

            在前者中,PEN_IRQ_NUM是中斷號,可以指定,也可以動態(tài)分配。在該驅(qū)動程序中,指定筆中斷分配中斷號為19;handle_pen_irq是中斷處理函數(shù),IRQ_FLG_STD是申請時(shí)的選項(xiàng),它決定中斷處理程序的一些特性,這里表示由系統(tǒng)內(nèi)部占用;touch_ screen是設(shè)備名。在后者中,程序向內(nèi)核注冊SPI中斷,用來在CPU和外設(shè)間傳遞數(shù)據(jù),分配的中斷號是0,handle_spi_irq是SPI中斷處理函數(shù)。

            此外,在觸摸屏驅(qū)動初始化子函數(shù)init_ts_drv()中,進(jìn)行了如下工作:

            (1)觸摸屏狀態(tài)的初始化;

            (2)筆信息(pen_values)的初始化;

            (3)初始化定時(shí)器并設(shè)置超時(shí)函數(shù)handle_timeout();

            (4)初始化寄存器。初始化等待隊(duì)列,等待隊(duì)列是由等待觸摸事件發(fā)生的進(jìn)程組成的一個(gè)隊(duì)列,它包括頭尾指針和一個(gè)正在睡眠進(jìn)程的鏈表;

            (5)設(shè)置觸摸屏狀態(tài)為空閑。

            由于這里的初始化會占用一部分系統(tǒng)資源,所以把它們放在了打開設(shè)備時(shí)處理,而不是最初的設(shè)備初始化部分,這樣也是出于節(jié)省資源的考慮。

            3.2.3讀函數(shù)ts_read()

            一旦用戶程序調(diào)用read()對觸摸屏進(jìn)行讀操作,則驅(qū)動程序調(diào)用入口點(diǎn)函數(shù)ts_read()進(jìn)行處理。如果此時(shí)沒有數(shù)據(jù)到來,且驅(qū)動程序選擇阻塞型操作,則調(diào)用interruptible_sleep_on(queue->proc_list)將進(jìn)程阻塞,并進(jìn)入等待隊(duì)列,同時(shí)設(shè)置觸摸屏狀態(tài)為等待;如果選擇了非阻塞型操作,則程序在沒有數(shù)據(jù)到達(dá)的時(shí)候立即返回,然后用異步觸發(fā)fasync()來通知數(shù)據(jù)的到來。

            在等待數(shù)據(jù)到來的過程中,如果有觸摸動作(筆中斷pen_irq)發(fā)生,則進(jìn)入中斷處理程序。在中斷處理程序中對數(shù)據(jù)進(jìn)行采樣和轉(zhuǎn)化,把當(dāng)前坐標(biāo)信息放入隊(duì)列中。在進(jìn)程被喚醒后(使用wake_up_interruptible(queue->proc_list)來喚醒進(jìn)程),程序把位置坐標(biāo)信息、事件序列信息等從隊(duì)列中取出,放入用戶空間(put_user),從而可以被用戶程序使用,避免了用戶直接和硬件打交道。

            3.2.4驅(qū)動程序的中斷處理函數(shù)

            當(dāng)筆中斷發(fā)生,程序進(jìn)入中斷處理函數(shù)。在中斷處理函數(shù)中,將完成對兩個(gè)中斷進(jìn)行處理,分別是外部的觸摸中斷(筆中斷)和SPI數(shù)據(jù)轉(zhuǎn)換中斷。與這兩個(gè)中斷對應(yīng)的中斷處理函數(shù),是觸摸屏軟件設(shè)計(jì)的關(guān)鍵所在。

            驅(qū)動程序在中斷處理函數(shù)中使用定時(shí)器處理時(shí)間相關(guān)操作。定義函數(shù)set_timer_irq(),如下:

            staticvoidset_timer_irq(structtimer_list*timer,intdelay){

            del_timer(timer);

            timer->expires=jiffies+delay;

            add_timer(timer);

            }

            jiffies是一個(gè)表征系統(tǒng)自從啟動以來到當(dāng)前為止所運(yùn)行時(shí)鐘數(shù)的變量,delay是設(shè)定的延長時(shí)間(用時(shí)鐘數(shù)作為計(jì)數(shù)單位)。一旦時(shí)鐘數(shù)超過設(shè)定值,則觸發(fā)超時(shí)函數(shù),在本程序中是handle_timeout( )。引入定時(shí)器的目的有兩個(gè):一是可以較為精確地控制系統(tǒng)由于消除電平升降造成信號抖動所需要時(shí)間,二是能夠有效控制采樣坐標(biāo)的數(shù)量,而不必引入占用大量系統(tǒng)資源的簡單延時(shí)函數(shù)。使用SPI中斷而產(chǎn)生大量坐標(biāo)數(shù)據(jù)這一問題在文獻(xiàn)中沒有很好的解決辦法,只是簡單地降低SPI時(shí)鐘頻率以取較少的數(shù)據(jù)量。本設(shè)計(jì)中引入定時(shí)器,可以很好地解決上述問題。

            在handle_timeout()函數(shù)中,程序利用條件選擇語句,對觸摸屏狀態(tài)值(ts_drv_state)進(jìn)行判斷,如果是非Error狀態(tài),則使能SPI,進(jìn)入handle_spi_irq(),與ADS7843進(jìn)行數(shù)據(jù)通訊。在handle_spi_irq()中,程序利用條件選擇語句,根據(jù)觸摸屏狀態(tài)值(ts_drv_state)來進(jìn)行數(shù)據(jù)轉(zhuǎn)換操作,通過向觸摸屏控制芯片發(fā)送前文中提到的控制字,來得到X和Y方向的坐標(biāo)。具體邏輯可參見程序流程圖。一旦一次轉(zhuǎn)換完成,程序?qū)⒏鶕?jù)點(diǎn)擊狀態(tài)信息(state_counter)來鑒別點(diǎn)擊的性質(zhì),在cause_event()函數(shù)中,分別對點(diǎn)擊和移動做出了判斷。判定方法較為簡單,只需將前后兩次采樣坐標(biāo)之差與移動閾值比較即可得出結(jié)論。此外,還區(qū)分了信號誤差和由于筆移動造成的坐標(biāo)改變,判別閾值可以由用戶自己設(shè)定。

            3.2.5I/O控制

            對于硬件各個(gè)參數(shù),包括采樣時(shí)間、消除抖動開關(guān)、消除抖動時(shí)間,都可以通過I/O控制函數(shù)ioctl()在用戶程序里進(jìn)行設(shè)定,避免每次都直接改變驅(qū)動程序,并重新編譯內(nèi)核所帶來的時(shí)間開銷。本程序中對I/O控制函數(shù)的定義是:staticintts_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg);其中,參數(shù)cmd有兩個(gè)值,分別為:TS_PARAMS_GET和TS_PARAMS_SET,它們用來指出是獲取參數(shù)還是設(shè)定參數(shù)。用戶在調(diào)用這個(gè)函數(shù)的時(shí)候,只需要對這個(gè)參數(shù)按照事先約定的格式賦值,就可以方便地獲取或者改變觸摸屏當(dāng)前參數(shù),arg是指向所傳遞參數(shù)的指針。

            4結(jié)論

            在獲得觸摸點(diǎn)的原始坐標(biāo)(數(shù)值范圍由所選用的A/D轉(zhuǎn)換器位數(shù)決定)后,還要根據(jù)具體使用的液晶屏實(shí)際像素進(jìn)行轉(zhuǎn)換,以方便圖形界面的后續(xù)開發(fā)??紤]到相鄰兩次的移動閾值,按照如下公式對觸摸屏坐標(biāo)進(jìn)行計(jì)算:

            

            其中XV為觸摸點(diǎn)X坐標(biāo)顯示值,XW為觸摸點(diǎn)X坐標(biāo)測量值(原始坐標(biāo)值),(1)、(2)、(3)式在觸摸屏初始化時(shí)得到,方法是任取觸摸屏X方向左側(cè)和右側(cè)各一點(diǎn),以X△V=X△W=1,Xoffrer=0為初始值進(jìn)行測量得到新的3個(gè)參數(shù):X△V、X△W和Xoffrer(在實(shí)際使用中此項(xiàng)工作屬于校準(zhǔn)零點(diǎn)偏移),然后這3個(gè)參數(shù)就不再變動,對于每次測量到的任意觸摸點(diǎn)原始坐標(biāo)XW,直接代入(4)式求出觸摸點(diǎn)的像素顯示坐標(biāo)XV。其中,XV1為觸摸屏左側(cè)點(diǎn)坐標(biāo)顯示值;XV2為觸摸屏右側(cè)點(diǎn)坐標(biāo)顯示值;XW1為觸摸屏左側(cè)點(diǎn)坐標(biāo)測量值;XW2為觸摸屏右側(cè)點(diǎn)坐標(biāo)測量值。

            本設(shè)計(jì)使用MicroWindows作為用戶界面,定制出每個(gè)桌面圖標(biāo)的坐標(biāo)區(qū)域,結(jié)合觸摸屏的采樣坐標(biāo),判斷是否在圖標(biāo)區(qū)域坐標(biāo)內(nèi),然后做出相應(yīng)的事件處理。對于本設(shè)計(jì)中使用的開發(fā)平臺,液晶屏是320240點(diǎn)陣的,物理尺寸為: 80mm60mm,ADS7843選擇12位轉(zhuǎn)換精度,觸摸屏理論分辨率為80/212=0.020mm,但是由于電平干擾和觸摸動作發(fā)生時(shí)的物理干擾,實(shí)際的精度無法達(dá)到這個(gè)值。經(jīng)過測試,在我們平臺上對同一點(diǎn)的點(diǎn)擊精度可以達(dá)到1.0mm。本驅(qū)動程序可以有效地區(qū)分點(diǎn)擊和移動信號,如果配合手寫識別軟件,能夠作為手寫板的底層驅(qū)動使用,實(shí)現(xiàn)手寫輸入。



          關(guān)鍵詞: μClinux 觸摸屏

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();