基于A(yíng)DSP-BF561的嵌入式鍵盤(pán)設計
1 引言
本文引用地址:http://dyxdggzs.com/article/265784.htm隨著(zhù)電子信息技術(shù)的飛速發(fā)展,信息家電和各式各樣的移動(dòng)終端得到越來(lái)越廣泛的應用。在這些人機交互( HMI)較頻繁的嵌入式系統中,鍵盤(pán)是一種應用昀為廣泛的輸入設備。由于嵌入式系統具有功耗低、體積小、專(zhuān)用性強等特點(diǎn),因此嵌入式鍵盤(pán)常常要求具有特殊的工作方式和特定的驅動(dòng)設計。
本文討論了基于 ADSP-BF561的非編碼矩陣鍵盤(pán)的硬件設計,并詳細闡述和分析了鍵盤(pán)驅動(dòng)程序實(shí)現中的關(guān)鍵問(wèn)題。ADSP-BF561是 Analog Devices Inc.推出的針對多媒體和通信應用方面的一款高性能 DSP產(chǎn)品,具有快速的數據處理能力和豐富的外設接口,已廣泛使用在各種網(wǎng)絡(luò )多媒體應用中。
該鍵盤(pán)設計已應用于一款以 uClinux 2.6和 ADSP-BF561作為軟硬件核心的網(wǎng)絡(luò )視頻電話(huà)終端產(chǎn)品,在實(shí)際應用中表現出較好的穩定性和實(shí)時(shí)性。
2 硬件設計方案
鍵盤(pán)的結構通常有兩種形式:線(xiàn)性鍵盤(pán)和矩陣鍵盤(pán)。在線(xiàn)性鍵盤(pán)中,每個(gè)按鍵都和一個(gè) I/O口連接,資源利用率不高,一般只適用于按鍵較少的場(chǎng)合。矩陣鍵盤(pán)連接方式利用(N+M)個(gè) I/O口,可以輸入 (N×M)個(gè)按鍵開(kāi)關(guān)。根據矩陣鍵盤(pán)識別鍵值方式的不同,又可分為編碼式鍵盤(pán)和非編碼鍵盤(pán)兩種。
本設計采用非編碼矩陣鍵盤(pán)實(shí)現。鍵盤(pán)電路由 5根行線(xiàn)和 6根列線(xiàn)組成,共使用 BF561的 11個(gè) GPIO(General purpose I/O port,通用輸入輸出)口,其接口電路如圖 1所示。

圖1鍵盤(pán)接口電路圖
該矩陣電路的 5個(gè)行引腳分別被接到 BF561的 GPIO43-GPIO47端口上,并且這五個(gè)端口被配置成輸入口,共用一個(gè)中斷源。同時(shí),將 6根列線(xiàn)分別接到 BF561的GPIO37-GPIO42端口上,配置為輸出口。在矩陣鍵盤(pán)中,每條水平線(xiàn)和垂直線(xiàn)在交叉處都不直接連通,而是通過(guò)一個(gè)按鍵加以連接。當按鍵沒(méi)有按下時(shí),所有的輸入端都是高電平,代表無(wú)鍵按下,由于列線(xiàn)輸出是低電平,一旦有鍵按下,則輸入線(xiàn)(行線(xiàn))就會(huì )被拉低,這樣便可以通過(guò) GPIO口產(chǎn)生中斷,通知處理器有鍵按下。
3 鍵盤(pán)驅動(dòng)的實(shí)現
本設計利用 GPIO口來(lái)直接掃描矩陣鍵盤(pán),從而簡(jiǎn)化了掃描電路的設計,降低了成本,但鍵盤(pán)的消抖、掃描等問(wèn)題都需由軟件來(lái)妥善解決。
3.1 按鍵消抖
當按鍵被按下或抬起的瞬間,由于觸點(diǎn)的彈性作用,會(huì )產(chǎn)生機械抖動(dòng),一般持續幾毫秒到十幾毫秒。這種抖動(dòng)對于用戶(hù)來(lái)說(shuō)是感覺(jué)不到的,但嵌入式系統微處理器的運行速度(即便是采用低速晶振)相對于人的手動(dòng)動(dòng)作是非常迅速的(處理器的速度是在微秒級,而機械抖動(dòng)的時(shí)間至少是毫秒級的)。因此,有可能只按了一次按鍵,可是處理器卻已執行了多次中斷的操作。
為了避免將用戶(hù)的一次按鍵誤當作幾次按鍵來(lái)處理,必須要想辦法去掉這種抖動(dòng)。本文通過(guò) uClinux提供的定時(shí)器機制,利用定時(shí)時(shí)間取代傳統的忙等方法,提高了系統的性能。當鍵盤(pán)上有鍵被按下時(shí),鍵盤(pán)中斷處理程序被觸發(fā),其主要實(shí)現流程如下:
static void key_enter_irq(int idx, void *id)
{
關(guān)中斷;
kbd_Scan_timer.expires = jiffies + 2; //指定定時(shí)器到期的時(shí)間
add_timer(&kbd_Scan_timer); //將一個(gè) timer_list對象掛入定時(shí)器隊列
}
該定時(shí)器對象(kbd_Scan_timer)需在模塊初始化函數中定義,并指定相應的處理函數。當定時(shí)器到期時(shí),內核就執行指定的函數,完成以下一些工作:掃描鍵盤(pán),得到被按下鍵的掃描碼,查表轉換成相應的鍵值后送入指定緩沖區中,開(kāi)中斷并等待應用程序接收。
3.2 鍵值掃描
在確定有鍵被按下后,即可進(jìn)入確定具體閉合鍵的過(guò)程。驅動(dòng)程序中采用掃描法實(shí)現按鍵的確定。由于行線(xiàn)連接在 GPIO的輸入口,且共用一個(gè)中斷輸入口,因此,在中斷到來(lái)時(shí),需要確定被按下的鍵在哪一行哪一列。
具體實(shí)現過(guò)程如圖 2所示:依次將列線(xiàn)置為低電平,即置某根列線(xiàn)為低電平時(shí),把其他列線(xiàn)置為高電平。在確定某根列線(xiàn)為低電平后,再逐行檢測各行線(xiàn)的電平狀態(tài)。若某行為低,則該行線(xiàn)與置為低電平的列線(xiàn)交叉處的按鍵即為閉合按鍵。由此便可得到閉合鍵的行值和列值,通常這就是一個(gè)掃描碼,然后可采用計算法或者查表法將閉合鍵的掃描碼轉換成應用程序所能夠理解的鍵值。

圖2掃描算法流程圖
3.3 緩沖區同步
得到閉合鍵的掃描碼后,通常將掃描碼轉換成應用程序可以理解的鍵值后放入一個(gè)緩沖區中,直到應用程序處理按鍵為止。緩沖是一個(gè)很有用的措施,當應用程序在按鍵事件發(fā)生了卻不能及時(shí)處理它們時(shí),通過(guò)緩沖區就可以防止按鍵丟失。緩沖區的大小取決于應用程序的需要。一般來(lái)說(shuō),都是把緩沖區作為一個(gè)環(huán)形隊列來(lái)管理。
環(huán)形緩沖區通常有一個(gè)讀指針和一個(gè)寫(xiě)指針(如圖 3所示)。通過(guò)移動(dòng)讀指針和寫(xiě)指針就可以實(shí)現緩沖區的數據讀取和寫(xiě)入。當一個(gè)按鍵被按下時(shí),鍵值將被放置在環(huán)形隊列的寫(xiě)指針指向的位置。而應用程序則是通過(guò)讀指針去讀取緩沖區中的鍵值。若緩沖區已滿(mǎn),則任何下一個(gè)按鍵都將被丟棄。若緩沖區為空,則讀進(jìn)程阻塞。使用環(huán)形的緩沖區可以使得讀寫(xiě)并發(fā)執行,讀進(jìn)程和寫(xiě)進(jìn)程可以采用 “生產(chǎn)者和消費者”的模型來(lái)訪(fǎng)問(wèn)緩沖區,從而方便了緩沖的使用和管理,確保系統的安全性。

圖3環(huán)形緩沖區
應用層中使用了 select系統調用,select會(huì )在一個(gè)循環(huán)中對每個(gè)需要監聽(tīng)的設備調用它們各自的 poll支持函數以使得當前進(jìn)程被加入各個(gè)設備的等待隊列。若當前沒(méi)有任何被監聽(tīng)的設備就緒,則內核進(jìn)行調度(調用 schedule),當前進(jìn)程讓出 CPU進(jìn)入阻塞狀態(tài),schedule返回時(shí)將再次循環(huán)檢測是否有操作可以進(jìn)行,如此反復;否則,若有任意一個(gè)設備就緒,select都立即返回。
poll 函數中利用等待隊列,實(shí)現了應用程序對緩沖區讀操作的同步。因此,只需再定義
兩個(gè)信號量,用于實(shí)現同步和互斥:
static DECLARE_MUTEX(mutex_sem); /*定義用于互斥的信號量,初值為1*/
/*定義控制驅動(dòng)程序寫(xiě)緩沖區的信號量,初值為 KEYBUF_SIZE-1,表示緩沖區中的空位
數 */
struct semaphore empty_sem;
sema_init (&empty_sem, KEYBUF_SIZE-1);
驅動(dòng)程序填寫(xiě)緩沖區過(guò)程的偽代碼如下:
down(empty_sem); //保證緩沖區中有空位,否則進(jìn)程掛起
down(mutex_sem); //申請互斥信號量,保證對緩沖區的互斥訪(fǎng)問(wèn)
鍵值送往環(huán)形緩沖寫(xiě)指針所指地址;
char_buf_write =( char_buf_write +1) mod KEYBUF_SIZE;//修改寫(xiě)指針
up(mutex_sem); //釋放互斥信號量
wake_up(&key_wait); //喚醒等待隊列中的進(jìn)程
應用程序讀緩沖區過(guò)程的內核實(shí)現偽代碼如下:
down(mutex_sem); //申請互斥信號量,保證對緩沖區的互斥訪(fǎng)問(wèn)
環(huán)形緩沖讀指針所指地址的值送往用戶(hù)空間;
char_buf_read =( char_buf_read +1) mod KEYBUF_SIZE;//修改讀指針
up(mutex_sem); //釋放互斥信號量
4 結束語(yǔ)
本文設計并實(shí)現了基于 ADSP-BF561的嵌入式矩陣鍵盤(pán)。利用 GPIO口直接掃描矩陣鍵盤(pán),簡(jiǎn)化了掃描電路的設計,降低了成本;軟件實(shí)現上,利用定時(shí)器消抖,避免忙等,提高系統效率;利用環(huán)形緩沖管理按鍵信息,使用等待隊列和信號量實(shí)現緩沖的同步操作。
目前,此設計已經(jīng)成功應用于一款網(wǎng)絡(luò )視頻電話(huà)終端,測試表明,該方案在一定的要求 下完全符合性能要求,并具有較好的穩定性和實(shí)時(shí)性。
本文作者創(chuàng )新點(diǎn):本設計利用定時(shí)器消抖,避免忙等,提高系統效率;利用環(huán)形緩沖管理按鍵信息,使用等待隊列和信號量實(shí)現緩沖的安全同步。
評論