国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

觸摸屏歸納為輸入子系統(tǒng)

發(fā)布時間:2016-4-5 17:37    發(fā)布者:信盈達(dá)電子

觸摸屏歸納為輸入子系統(tǒng),這里主要是針對電阻屏,其使用過程如下
當(dāng)用觸摸筆按下時,產(chǎn)生中斷。
在中斷處理函數(shù)處理函數(shù)中啟動ADC轉(zhuǎn)換x,y坐標(biāo)。
ADC結(jié)束,產(chǎn)生ADC中斷
在ADC中斷處理函數(shù)里上報(input_event)啟動定時器
再次啟動定時器(可以處理滑動、長按)
松開按鍵

其驅(qū)動程序的寫法和之前寫輸入子系統(tǒng)的寫法基本上一致。
寫出入口函數(shù),出口函數(shù)并加以修飾,加入相關(guān)頭文件,然后開始完善各函數(shù),在入口函數(shù)中分配input_dev結(jié)構(gòu)體,設(shè)置(能產(chǎn)生哪類事件,能產(chǎn)生這類事件中的哪些事件),注冊設(shè)備,硬件相關(guān)的操作等。出口函數(shù)中主要對之前注冊、分配的一些資源進(jìn)行釋放。
還應(yīng)根據(jù)2440數(shù)據(jù)手冊ADC轉(zhuǎn)換和觸摸屏那一章,對相關(guān)寄存器根據(jù)實際需要進(jìn)行設(shè)置。

點擊(此處)折疊或打開

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct s3c_ts_regs {                     /* 相關(guān)的寄存器 */
    unsigned long adccon;
    unsigned long adctsc;
    unsigned long adcdly;
    unsigned long adcdat0;
    unsigned long adcdat1;
    unsigned long adcupdn;
};
static struct input_dev *s3c_ts_dev;
static volatile struct s3c_ts_regs *s3c_ts_regs;
static struct timer_list ts_timer;
void enter_wait_pen_down_mode(void)  /* 進(jìn)入等待觸摸筆按下模式 */
{
    s3c_ts_regs->adctsc = 0xd3;      /* 進(jìn)入等待中斷模式 bit[8]為0 2440手冊P442 */
}
void enter_wait_pen_up_mode(void)       /* 進(jìn)入等待觸摸筆松開模式 */
{
    s3c_ts_regs->adctsc = 0x1d3;        /* 進(jìn)入等待中斷模式 bit[8]為1 2440手冊P442 */
}
static void enter_measure_xy_mode(void) /* 進(jìn)入xy測量模式 */
{
    s3c_ts_regs->adctsc = (1<<3) | (1<<2);
}
static void start_adc(void)
{
    s3c_ts_regs->adccon |= (1<<0);       /* 啟動ADC */
}
static int s3c_filter_ts(int x[, int y[)      /* 軟件過濾 */
{
#define ERR_LIMIT 10      /* 經(jīng)驗值,容差值 */
    int avr_x, avr_y;
    int det_x, det_y;
    avr_x = (x[0 + x[1)/2;
    avr_y = (y[0 + y[1)/2;
    det_x = (x[2 > avr_x) ? (x[2 - avr_x) : (avr_x - x[2);
    det_y = (y[2 > avr_y) ? (y[2 - avr_y) : (avr_y - y[2);
    if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))
        return 0;
    avr_x = (x[1 + x[2)/2;
    avr_y = (y[1 + y[2)/2;
    det_x = (x[3 > avr_x) ? (x[3 - avr_x) : (avr_x - x[3);
    det_y = (y[3 > avr_y) ? (y[3 - avr_y) : (avr_y - y[3);
    if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))
        return 1;
}
static void s3c_ts_timer_functions(unsigned long data)
{
    if (s3c_ts->adcdat0 & (1<<15))   /* 假設(shè)時間到 */
    {
        /* 如果觸摸已經(jīng)松開 */
        input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);   /* 上報事件,壓力值為0 */
        input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
        input_sync(s3c_ts_dev);    /* 上報完后要同步 */
        enter_wait_pen_down_mode();  /* 進(jìn)入觸摸等待模式 */
    }
    else
    {
        /* 否則測量x,y坐標(biāo) */
        enter_measure_xy_mode();
        start_adc();
    }
}
static irqreturn_t pen_down_up_irq(int irq, void *dev id)
{
    if (s3c_ts->adcdat0 & (1<<15))   /* 2440手冊P447 ADCDAT0寄存器 */
    {
        printk("pen up\n");
        enter_wait_pen_down_mode();
    }
    else
    {
        //printk("pen down\n");
        //enter_wait_pen_up_mode();
        enter_measure_xy_mode();
        start_adc();
    }
    return IRQ_HANDLED;
}
static irqreturn_t adc_irq(int irq, void *dev id)
{
    static int cnt = 0;
    static int x[4, y[4;
    int adcdat0, adcdat1;
    /* 優(yōu)化措施2
     * 如果ACD完成時,發(fā)現(xiàn)觸摸筆已松開,則丟棄此次結(jié)果
     */
    adcdat0 = s3c_ts_regs->adcdat0;
    adcdat1 = s3c_ts_regs->adcdat1;
    if (s3c_ts->adcdat0 & (1<<15))     /* bit[15判斷是否松開 */
    {
        /* 如果已經(jīng)松開則丟棄結(jié)果 */
        cnt = 0;
        input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);   /* 上報事件,壓力值為0 */
        input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
        input_sync(s3c_ts_dev);
        enter_wait_pen_up_mode();
    }
    else
    {
        /* 如果還是按下,則打印結(jié)果并進(jìn)入等待松開模式 */
        //printk("adc_irq cnt = %d,x = %d, y = %d\n", ++cnt, adcdat0 & 0x3ff, adcdat1 & 0x3ff);
        /* 優(yōu)化措施3:
         * 多次測量取平均值
         */
        x[cnt = adcdat0 & 0x3ff;    /* 將測量結(jié)果存入靜態(tài)變量中 */
        y[cnt = adcdat1 & 0x3ff;
        ++cnt;
        if (cnt == 4)
        {
            /* 優(yōu)化措施4
             * 軟件過濾
             */
             if (s3c_filter_ts(x, y))
            {
                //printk("x = %d, y = %d\n", (x[0+x[1+x[2+x[3)/4, (y[0+y[1+y[2+y[3)/4);
                input_report_abs(s3c_ts_dev, ABS_X, (x[0+x[1+x[2+x[3)/4);
                input_report_abs(s3c_ts_dev, ABS_Y, (y[0+y[1+y[2+y[3)/4);
                input_report_abs(s3c_ts_dev, ABS_PRESSURE, 1);
                input_report_key(s3c_ts_dev, BTN_TOUCH, 1);
                input_sync(s3c_ts_dev);
            }
            cnt = 0;    /* cnt計數(shù)清0 */
            enter_wait_pen_up_mode();       /* 測量完后要進(jìn)入等待松開模式,這樣才能連續(xù)操作 */
            /* 啟動定時器處理長按/滑動的情況 */
            mod_timer(&ts_timer, jiffies + HZ/100);  /* 1HZ/100 = 10ms */
        }
        else    /* 否則再測量一次 */
        {
            enter_measure_xy_mode();
            start_adc();
        }
    }
        return IRQ_HANDLED;
}
static int s3c_ts_init(void)
{
    struct clk* clk;
    /* 1.分配一個input_dev結(jié)構(gòu)體 */
    s3c_ts_dev = input_allocate_device();
    /* 2.設(shè)置 */
    /* 2.1 能產(chǎn)生哪類事件 */
    set_bit(EV_KEY, s3c_ts_dev->evbit);  /* 能夠產(chǎn)生按鍵事件 */
    set_bit(EV_ABS, s3c_ts_dev->evbit);  /* 能夠產(chǎn)生絕對位移事件 */
    /* 2.2 能產(chǎn)生這類事件里的哪些事件 */
    set_bit(BTN_TOUCH, s3c_ts_dev->evbit); /* 能夠產(chǎn)生按鍵類里面的觸摸屏事件 */
    input_set_abs_params(s3c_ts_dev, ABS_X, 0, 0x3FF, 0, 0);   /* X方向 0xFF是因為觸摸屏ADC是10位 */
    input_set_abs_params(s3c_ts_dev, ABS_Y, 0, 0x3FF, 0, 0);   /* Y方向 */
    input_set_abs_params(s3c_ts_dev, ABS_PRESSURE, 0, 1, 0, 0);/* 壓力方向 */
    /* 3.注冊 */
    input_register_device(s3c_ts_dev);
    /* 4.硬件相關(guān)的操作 */
    /* 4.1 使能時鐘CLKCON[15 (總開關(guān),一般對不用的設(shè)備,時鐘一般是關(guān)閉的) */
    clk = clk_get(NULL, "adc");
    clk_enable(clk);
    /* 4.2 設(shè)置S3c2440的ADC/TS寄存器 */
    s3c_ts_regs = ioremap(0x58000000, sizeof(struct s3c_ts_regs));
    /* ADCCON
     * bit[14   : 1 預(yù)分頻使能
     * bit[13:6 :   預(yù)分頻系數(shù)
     *               49 ,ADCCLK = PCLK/(49+1) = 50MHz/(49+1)=1MHz
     * bit[5:3  : 多路選擇
     * bit[2    : 省電模式選擇
     * bit[1    : AD啟動方式,通過讀來啟動
     * bit[0    : 啟動AD轉(zhuǎn)換,啟動后會自動清零
     */
    s3c_ts_regs->adccon = (1<<14) | (49<<6);
    request_irq(IRQ_TC, pen_down_up_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL);
    request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc", NULL);
    /* 優(yōu)化措施1
     * 設(shè)置ADCDLY為最大值,使得電壓穩(wěn)定后再發(fā)出中斷IRQ_TC
     */
    s3c_ts_regs->adcdly   = 0xffff;
    /* 優(yōu)化措施5
     * 使用定時器,用來解決連按或滑動
     */
    init_timer(&ts_timer);
    ts_timer.function = s3c_ts_timer_function;
    add_timer(&ts_timer);
    enter_wait_pen_down_mode();
    return 0;
}
static void s3c_ts_exit(void)
{
    free_irq(IRQ_TC, NULL);
    free_irq(IRQ_ADC, NULL);
    iounmap(s3c_ts_regs);
    input_unregister_device(s3c_ts_dev);
    input_free_device(s3c_ts_dev);
    del_timer(&ts_timer);
}
module_init(s3c_ts_init);
module_exit(s3c_ts_exit);
MODULE_DESCRIPTION("s3c_ts driver for the s3c2440");
MODULE_LICENSE("GPL");




測試方法主要是檢測上報事件是否正常,要想更好的測試,需要移植ts_lib這方面的資料網(wǎng)上都可以找到。
以tslib-1.4.tar.gz為例
sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install libtool




編譯:
tar xzf tslib-1.4.tar.gz
cd tslib
./autogen.sh

mkdir tmp      // 安裝目錄
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache
./configure --host=arm-linux --cache-file=arm-linux.cache --prefix=$(pwd)/tmp
make
make install

安裝:
cd tmp
cp * -rf /nfsroot    //  /nfsroot可根據(jù)實際情況來定


使用:

先安裝s3c_ts.ko, lcd.ko     // lcd.ko是之前編譯好的LCD驅(qū)動,如果后面編譯s3c_ts時改過配置,直接裝載之前編譯好的lcd.ko可能會出現(xiàn)段錯誤,重新編譯一下lcd驅(qū)動就可以了。

1.
修改 /etc/ts.conf第1行(去掉#號和第一個空格):
# module_raw input
改為:
module_raw input

2.
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

ts_calibrate

ts_test

更多C語言 C++、JAVA、數(shù)電模電、51單片機(jī)PIC stm32 ARM Linux驅(qū)動 嵌入式、安卓系統(tǒng) FPGADSP Cortex-M3學(xué)習(xí)

請咨詢  朱工,騰訊QQ3208919269  中國移動15088133726  深圳南山、民治、龍崗、西鄉(xiāng)、長沙、鄭州、南寧同步學(xué)習(xí)中! 

理論與實踐相結(jié)合 一線工程師項目經(jīng)理教學(xué) 結(jié)合真實的產(chǎn)品案列 讓你感受前所未有的電子產(chǎn)品的開發(fā)流程

2015給自己一個決心,只為自己!高薪就業(yè)不是夢,有想法你就來 IT達(dá)人等著你!!!


本文地址:http://m.qingdxww.cn/thread-162607-1-1.html     【打印本頁】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點和對其真實性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時間更正或刪除。
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區(qū)
  • 利用SAM E54 Xplained Pro評估工具包演示CAN轉(zhuǎn)USB橋接器以及基于CAN的主機(jī)和自舉程序應(yīng)用程序
  • 使用SAM-IoT Wx v2開發(fā)板演示AWS IoT Core應(yīng)用程序
  • 使用Harmony3加速TCP/IP應(yīng)用的開發(fā)培訓(xùn)教程
  • 集成高級模擬外設(shè)的PIC18F-Q71家族介紹培訓(xùn)教程
  • 貿(mào)澤電子(Mouser)專區(qū)
關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 黄色片在线看 | 久久天天躁狠狠躁夜夜2020一 | 亚洲欧美日韩另类在线一 | 黄网站在线观看视频 | 日韩亚洲国产欧美精品 | 亚洲欧美高清视频 | 手机av在线播放 | 一级日本高清视频免费观看 | 一级片在线免费观看 | 午夜精品久久影院蜜桃 | 黑人操白逼 | 成人欧美一区二区三区视频xxx | 91专区在线观看 | 国产欧美日韩一区二区三区在线 | 日韩在线中文 | 理论福利午夜 | 亚洲第一黄色网 | 热@国产| 国产精品麻豆a在线播放 | 二级特黄绝大片免费视频大片 | 啪啪一级| 国产91精品一区二区麻豆网站 | 永久天堂 | 免费手机黄色网站 | 国产精品一区91 | h肉动漫在线观看免费资源 h肉动漫在线观看高清 | 四虎免费在线播放 | 欧美一区二区在线免费观看 | 狠狠色狠狠色很很综合很久久 | 亚洲一区二区视频 | 中国精品久久精品三级 | 日韩福利视频 | 国产一区二三区 | 国产免费高清 | 久久嫩草影院免费看夜色 | 黑人视频在线观看 | 国产精品国产香蕉在线观看网 | 日本爽视频 | 99精品视频在线成人精彩视频 | 青青国产线免观看手机版精品 | 精品视频在线观看免费 |