嵌入式Linux設備驅(qū)動開發(fā)之:按鍵驅(qū)動程序?qū)嵗?/h1>
本文引用地址:http://butianyuan.cn/article/257107.htm按鍵掃描函數(shù)如下所示。首先根據(jù)中斷號確定操作按鍵所在行的位置,然后采用逐列掃描法最終確定操作按鍵所在的位置。
/*
**進入中斷后,掃描銨鍵碼
**返回:按鍵碼(1~16),0xff表示錯誤
*/
static__inlineunsignedcharbutton_scan(intirq)
{
unsignedcharkey_id=0xff;
unsignedcharcolumn=0xff,row=0xff;
s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_INP);/*GPF0*/
s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_INP);/*GPF2*/
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_INP);/*GPG3*/
s3c2410_gpio_cfgpin(S3C2410_GPG11,S3C2410_GPG11_INP);/*GPG11*/
switch(irq)
{/*根據(jù)irq值確定操作按鍵所在行的位置*/
caseIRQ_EINT0:
{
column=0;
}
break;
caseIRQ_EINT2:
{
column=1;
}
break;
caseIRQ_EINT11:
{
column=2;
}
break;
caseIRQ_EINT19:
{
column=3;
}
break;
}
if(column!=0xff)
{/*開始逐列掃描,掃描第0列*/
s3c2410_gpio_setpin(S3C2410_GPE11,0);/*將KSCAN0置為低電平*/
s3c2410_gpio_setpin(S3C2410_GPG6,1);
s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);
if(!s3c2410_gpio_getpin(key_info_matrix[column][0].irq_gpio_port))
{/*觀察對應的中斷線的輸入端口值*/
key_id=key_info_matrix[column][0].key_id;
returnkey_id;
}
/*掃描第1列*/
s3c2410_gpio_setpin(S3C2410_GPE11,1);
s3c2410_gpio_setpin(S3C2410_GPG6,0);/*將KSCAN1置為低電平*/
s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);
if(!s3c2410_gpio_getpin(key_info_matrix[column][1].irq_gpio_port))
{
key_id=key_info_matrix[column][1].key_id;
returnkey_id;
}
/*掃描第2列*/
s3c2410_gpio_setpin(S3C2410_GPE11,1);
s3c2410_gpio_setpin(S3C2410_GPG6,1);
s3c2410_gpio_setpin(S3C2410_GPE13,0);/*將KSCAN2置為低電平*/
s3c2410_gpio_setpin(S3C2410_GPG2,1);
if(!s3c2410_gpio_getpin(key_info_matrix[column][2].irq_gpio_port))
{
key_id=key_info_matrix[column][2].key_id;
returnkey_id;
}
/*掃描第3列*/
s3c2410_gpio_setpin(S3C2410_GPE11,1);
s3c2410_gpio_setpin(S3C2410_GPG6,1);
s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,0);/*將KSCAN3置為低電平*/
if(!s3c2410_gpio_getpin(key_info_matrix[column][3].irq_gpio_port))
{
key_id=key_info_matrix[column][3].key_id;
returnkey_id;
}
}
returnkey_id;
}
以下是read函數(shù)接口的實現(xiàn)。首先在按鍵緩沖中刪除已經(jīng)過時的按鍵操作信息,接下來,從按鍵緩沖中讀取一條信息(按鍵ID)并傳遞給用戶層。
/*從緩沖刪除過時數(shù)據(jù)(5s前的按鍵值)*/
staticvoidremove_timeoutkey(void)
{
unsignedlongtick;
spin_lock_irq(buffer_lock);/*獲得一個自旋鎖*/
while(key_buffer.head!=key_buffer.tail)
{
tick=get_tick_count()-key_buffer.jiffy[key_buffer.head];
if(tick5000)/*5s*/
break;
key_buffer.buf[key_buffer.head]=0;
key_buffer.jiffy[key_buffer.head]=0;
key_buffer.head++;
key_buffer.head=(MAX_KEY_COUNT-1);
}
spin_unlock_irq(buffer_lock);/*釋放自旋鎖*/
}
/*讀鍵盤*/
staticssize_tbutton_read(structfile*filp,
char*buffer,size_tcount,loff_t*f_pos)
{
ssize_tret=0;
remove_timeoutkey();/*刪除過時的按鍵操作信息*/
spin_lock_irq(buffer_lock);
while((key_buffer.head!=key_buffer.tail)(((size_t)ret)count))
{
put_user((char)(key_buffer.buf[key_buffer.head]),buffer[ret]);
key_buffer.buf[key_buffer.head]=0;
key_buffer.jiffy[key_buffer.head]=0;
key_buffer.head++;
key_buffer.head=(MAX_KEY_COUNT-1);
ret++;
}
spin_unlock_irq(buffer_lock);
returnret;
}
以上介紹了按鍵驅(qū)動程序中的主要內(nèi)容。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
linux相關文章:linux教程
蜂鳴器相關文章:蜂鳴器原理
按鍵掃描函數(shù)如下所示。首先根據(jù)中斷號確定操作按鍵所在行的位置,然后采用逐列掃描法最終確定操作按鍵所在的位置。
/*
**進入中斷后,掃描銨鍵碼
**返回:按鍵碼(1~16),0xff表示錯誤
*/
static__inlineunsignedcharbutton_scan(intirq)
{
unsignedcharkey_id=0xff;
unsignedcharcolumn=0xff,row=0xff;
s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_INP);/*GPF0*/
s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_INP);/*GPF2*/
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_INP);/*GPG3*/
s3c2410_gpio_cfgpin(S3C2410_GPG11,S3C2410_GPG11_INP);/*GPG11*/
switch(irq)
{/*根據(jù)irq值確定操作按鍵所在行的位置*/
caseIRQ_EINT0:
{
column=0;
}
break;
caseIRQ_EINT2:
{
column=1;
}
break;
caseIRQ_EINT11:
{
column=2;
}
break;
caseIRQ_EINT19:
{
column=3;
}
break;
}
if(column!=0xff)
{/*開始逐列掃描,掃描第0列*/
s3c2410_gpio_setpin(S3C2410_GPE11,0);/*將KSCAN0置為低電平*/
s3c2410_gpio_setpin(S3C2410_GPG6,1);
s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);
if(!s3c2410_gpio_getpin(key_info_matrix[column][0].irq_gpio_port))
{/*觀察對應的中斷線的輸入端口值*/
key_id=key_info_matrix[column][0].key_id;
returnkey_id;
}
/*掃描第1列*/
s3c2410_gpio_setpin(S3C2410_GPE11,1);
s3c2410_gpio_setpin(S3C2410_GPG6,0);/*將KSCAN1置為低電平*/
s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,1);
if(!s3c2410_gpio_getpin(key_info_matrix[column][1].irq_gpio_port))
{
key_id=key_info_matrix[column][1].key_id;
returnkey_id;
}
/*掃描第2列*/
s3c2410_gpio_setpin(S3C2410_GPE11,1);
s3c2410_gpio_setpin(S3C2410_GPG6,1);
s3c2410_gpio_setpin(S3C2410_GPE13,0);/*將KSCAN2置為低電平*/
s3c2410_gpio_setpin(S3C2410_GPG2,1);
if(!s3c2410_gpio_getpin(key_info_matrix[column][2].irq_gpio_port))
{
key_id=key_info_matrix[column][2].key_id;
returnkey_id;
}
/*掃描第3列*/
s3c2410_gpio_setpin(S3C2410_GPE11,1);
s3c2410_gpio_setpin(S3C2410_GPG6,1);
s3c2410_gpio_setpin(S3C2410_GPE13,1);
s3c2410_gpio_setpin(S3C2410_GPG2,0);/*將KSCAN3置為低電平*/
if(!s3c2410_gpio_getpin(key_info_matrix[column][3].irq_gpio_port))
{
key_id=key_info_matrix[column][3].key_id;
returnkey_id;
}
}
returnkey_id;
}
以下是read函數(shù)接口的實現(xiàn)。首先在按鍵緩沖中刪除已經(jīng)過時的按鍵操作信息,接下來,從按鍵緩沖中讀取一條信息(按鍵ID)并傳遞給用戶層。
/*從緩沖刪除過時數(shù)據(jù)(5s前的按鍵值)*/
staticvoidremove_timeoutkey(void)
{
unsignedlongtick;
spin_lock_irq(buffer_lock);/*獲得一個自旋鎖*/
while(key_buffer.head!=key_buffer.tail)
{
tick=get_tick_count()-key_buffer.jiffy[key_buffer.head];
if(tick5000)/*5s*/
break;
key_buffer.buf[key_buffer.head]=0;
key_buffer.jiffy[key_buffer.head]=0;
key_buffer.head++;
key_buffer.head=(MAX_KEY_COUNT-1);
}
spin_unlock_irq(buffer_lock);/*釋放自旋鎖*/
}
/*讀鍵盤*/
staticssize_tbutton_read(structfile*filp,
char*buffer,size_tcount,loff_t*f_pos)
{
ssize_tret=0;
remove_timeoutkey();/*刪除過時的按鍵操作信息*/
spin_lock_irq(buffer_lock);
while((key_buffer.head!=key_buffer.tail)(((size_t)ret)count))
{
put_user((char)(key_buffer.buf[key_buffer.head]),buffer[ret]);
key_buffer.buf[key_buffer.head]=0;
key_buffer.jiffy[key_buffer.head]=0;
key_buffer.head++;
key_buffer.head=(MAX_KEY_COUNT-1);
ret++;
}
spin_unlock_irq(buffer_lock);
returnret;
}
以上介紹了按鍵驅(qū)動程序中的主要內(nèi)容。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)linux相關文章:linux教程
蜂鳴器相關文章:蜂鳴器原理
評論