輸入子系統體系
• 核心層: linux_dir/drivers/input/input.c(提供最核心函式)
• 裝置事件層: linux_dir/drivers/input/evdev.c(提供handler)
提供輸入裝置產生的原始資料並上報給應用程式,這適用於
所有輸入裝置, 該觸控螢幕也不例外
編寫基於輸入子系統的驅動時只需:
1.分配input_dev
2.設定能產生什麼事件和這類事件的哪些事件
3. input_register_device註冊
4. 硬體操作
觸控螢幕硬體原理
1.分配input_dev
2.設定能產生什麼事件和這類事件的哪些事件
3. input_register_device註冊
/* 1. 分配乙個input結構體 */
s3c_ts_dev = input_allocate_device();
/* 2.設定 */
/* 2.1 能產生哪類事件 */
set_bit(ev_key,s3c_ts_dev->evbit);
set_bit(ev_abs,s3c_ts_dev->evbit);
/* 2.2 能產生按鍵類裡的哪些事件 */
set_bit(btn_touch, s3c_ts_dev->keybit);
input_set_abs_params(s3c_ts_dev, abs_x, 0, 0x3ff, 0, 0);
input_set_abs_params(s3c_ts_dev, abs_y, 0, 0x3ff, 0, 0);
input_set_abs_params(s3c_ts_dev, abs_pressure, 0, 1, 0, 0);
/* 3.註冊 */
input_register_device(s3c_ts_dev);
1.按下觸控螢幕產生中斷
2.在觸控螢幕中斷處理程式中,將通過adc採集的電壓值轉化為xy方向的座標值,然後啟動adc。
3.ad轉化結束產生adc中斷。
4.在adc中斷處理函式中上報事件,並啟動定時器(用於處理長按和滑動事件)
5.定時器時間到,跳到步驟2繼續往下執行
直到鬆開觸控螢幕
下面是硬體暫存器和中斷的設定,為上面觸控螢幕的操作做準備,程式為:
/* 4.硬體相關操作 */
/* 4.1 使能時鐘 */
clk = clk_get(null,"adc");
clk_enable(clk);
/* 4.2 設定s3c2440的adc/ts相關操作暫存器 */
// s3c_ts_regs = ioremap(0x58000000,(sizeof(struct s3c_ts_regs));
s3c_ts_regs = ioremap(0x58000000, sizeof(struct s3c_ts_regs));
/*bit[14] prscen :a/d converter 預分頻使能
* 1 = enable
*bit[13:6] prscvl : a/d converter prescaler value 預分頻係數
* 49 adclk = pclk/(49+1) = 50mhz / (49+1) = 1mhz
*bit[0] enable_start adc開始轉化使能 這裡先設為0,後面還會進行設定**
*/s3c_ts_regs->adccon = (1<<14) | (49<<6) | (0<<0);
/* 4.3 註冊中斷,當按下觸控螢幕時會產生中斷 */
request_irq(irq_tc,pen_down_up_irq,irqf_sample_random,"ts_pen",null);
/* 4.5 當adc轉化結束後,會產生adc轉化結束中斷 */
request_irq(irq_adc,adc_irq,irqf_sample_random,"adc",null);
enter_wait_pen_down_mode();
上面程式中的s3c_ts_regs是觸控螢幕暫存器的乙個總的集合,並將其放入乙個結構體中,**為:
struct s3c_ts_regs;
上面是準備**,下面我們將模仿觸控螢幕按下的過程來分析**:
假設我們程式已經寫好,並且在開發版上執行正常,當你拿起筆按在觸控螢幕上的一點,因為在之前我們已經註冊了irq_tc中斷:
/* 4.3 註冊中斷,當按下觸控螢幕時會產生中斷 */
request_irq(irq_tc,pen_down_up_irq,irqf_sample_random,"ts_pen",null);
所以當你按下螢幕時觸發中斷,從而處理相應的中斷處理函式:pen_down_up_irq,詳細的**為:
static irqreturn_t pen_down_up_irq(int irq, void *dev_id)
else
return irq_handled;
}
如上面程式所示,此時如果你抬起了你的筆,程式將上報事件,而如果你還處於按下狀態,我們將繼續跟著程式走:
由於你已經註冊了adc中斷:
/* 4.3 註冊中斷,當按下觸控螢幕時會產生中斷 */
request_irq(irq_tc,pen_down_up_irq,irqf_sample_random,"ts_pen",null);
而上面的程式已經開啟了adc:start_adc();
所以我們將進入adc的中斷處理函式adc_irq,詳細的**:
static irqreturn_t adc_irq(int irq, void *dev_id)
else
enter_wait_pen_up_mode();
cnt=0;
/* 啟動定時器處理長按和滑動情況 */
mod_timer(&ts_timer, jiffies + hz/100);
} else
} return irq_handled;
}
而通過上面的程式,我們知道了觸控螢幕的處理過程,此時,觸控螢幕驅動已經基本寫好了。而下面就是對特殊的處理,如當長按或者滑動時,此時我們將通過定時器來處理這樣的問題,假如此時你還沒有鬆手,觸控螢幕還處於按下狀態。(你可能覺得怎麼這麼長時間了筆還沒抬起啊,其實上面分析的可能麻煩,但在程式中上面的**還是跑的很快的)。那麼,我們接下來就是對定時器的分析了,因為在上文中我們啟動了定時器:mod_timer(&ts_timer,jiffies + hz/100);
當定時時間(此處我們設定定時時間為10ms)到時,進入定時器處理函式:
static void s3c_ts_timer_function(unsigned long data)
else
}
在上面的程式中,可以看出定時時間到後定時器又會啟動adc然後將接著步驟2繼續執行,一直這樣迴圈,直到鬆開,而這樣也就可以處理長按或者滑動了,當你長按或者滑動時,定時時間到後會採集你所在的位置的xy座標,然後上報,然後繼續進入定時器,繼續進入adc,繼續採集上報,直到你鬆開觸控螢幕。
好了,上面就是觸控螢幕驅動的大致流程和**分析了。
下面是進入不同模式和濾波的函式
static void enter_wait_pen_down_mode(void)
static void enter_wait_pen_up_mode(void)//檢測觸控筆等待鬆開
static void enter_measure_xy_mode(void)
static void start_adc(void)
static int s3c_filter_ts(int x, int y)
return 1;
}
QT 觸控螢幕 驅動
要 本文主要介紹了在嵌入式 linux 系統下基於 qt embeded 的觸控螢幕驅動的設計,通過對 linux 裝置 驅動和qt embedded裝置驅動介面的工作原理和機制介紹,並結合大量源 進行分析,提出了基於qt embeded 的觸控螢幕驅動的開發方案。linux 下的裝置驅動基礎 li...
觸控螢幕驅動分析
觸控螢幕的主要分為四種,分別是電阻式,電容感應式,紅外線式以及表面聲波式。我們現在我們主要談論是電阻式觸控螢幕。看下圖可以大概了解電阻式觸控螢幕。電阻式觸控螢幕的屏體部分是一塊與顯示器表面相匹配的多層復合薄膜,由一層玻璃或有機玻璃作為基層,表面塗有一層透明 的導電層,上面再蓋有一層外表面的硬化處理,...
觸控螢幕驅動分析
模組初始化 static int init s3c2410ts init void 獲得adc時鐘,並使能 對adc暫存器位址對映到記憶體 配置暫存器 gpio口 xm,xp,ym,yp,adc有關的暫存器 申請input裝置 設定可支援的事件為同步 按鍵 絕對座標事件 設定按鍵時間型別為觸控螢幕 ...