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

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

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

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

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

點(diǎn)擊(此處)折疊或打開(kāi)

#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手冊(cè)P442 */
}
void enter_wait_pen_up_mode(void)       /* 進(jìn)入等待觸摸筆松開(kāi)模式 */
{
    s3c_ts_regs->adctsc = 0x1d3;        /* 進(jìn)入等待中斷模式 bit[8]為1 2440手冊(cè)P442 */
}
static void enter_measure_xy_mode(void) /* 進(jìn)入xy測(cè)量模式 */
{
    s3c_ts_regs->adctsc = (1<<3) | (1<<2);
}
static void start_adc(void)
{
    s3c_ts_regs->adccon |= (1<<0);       /* 啟動(dòng)ADC */
}
static int s3c_filter_ts(int x[, int y[)      /* 軟件過(guò)濾 */
{
#define ERR_LIMIT 10      /* 經(jīng)驗(yàn)值,容差值 */
    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è)時(shí)間到 */
    {
        /* 如果觸摸已經(jīng)松開(kāi) */
        input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);   /* 上報(bào)事件,壓力值為0 */
        input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
        input_sync(s3c_ts_dev);    /* 上報(bào)完后要同步 */
        enter_wait_pen_down_mode();  /* 進(jìn)入觸摸等待模式 */
    }
    else
    {
        /* 否則測(cè)量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手冊(cè)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完成時(shí),發(fā)現(xiàn)觸摸筆已松開(kāi),則丟棄此次結(jié)果
     */
    adcdat0 = s3c_ts_regs->adcdat0;
    adcdat1 = s3c_ts_regs->adcdat1;
    if (s3c_ts->adcdat0 & (1<<15))     /* bit[15判斷是否松開(kāi) */
    {
        /* 如果已經(jīng)松開(kāi)則丟棄結(jié)果 */
        cnt = 0;
        input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);   /* 上報(bào)事件,壓力值為0 */
        input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
        input_sync(s3c_ts_dev);
        enter_wait_pen_up_mode();
    }
    else
    {
        /* 如果還是按下,則打印結(jié)果并進(jìn)入等待松開(kāi)模式 */
        //printk("adc_irq cnt = %d,x = %d, y = %d\n", ++cnt, adcdat0 & 0x3ff, adcdat1 & 0x3ff);
        /* 優(yōu)化措施3:
         * 多次測(cè)量取平均值
         */
        x[cnt = adcdat0 & 0x3ff;    /* 將測(cè)量結(jié)果存入靜態(tài)變量中 */
        y[cnt = adcdat1 & 0x3ff;
        ++cnt;
        if (cnt == 4)
        {
            /* 優(yōu)化措施4
             * 軟件過(guò)濾
             */
             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計(jì)數(shù)清0 */
            enter_wait_pen_up_mode();       /* 測(cè)量完后要進(jìn)入等待松開(kāi)模式,這樣才能連續(xù)操作 */
            /* 啟動(dòng)定時(shí)器處理長(zhǎng)按/滑動(dòng)的情況 */
            mod_timer(&ts_timer, jiffies + HZ/100);  /* 1HZ/100 = 10ms */
        }
        else    /* 否則再測(cè)量一次 */
        {
            enter_measure_xy_mode();
            start_adc();
        }
    }
        return IRQ_HANDLED;
}
static int s3c_ts_init(void)
{
    struct clk* clk;
    /* 1.分配一個(gè)input_dev結(jié)構(gòu)體 */
    s3c_ts_dev = input_allocate_device();
    /* 2.設(shè)置 */
    /* 2.1 能產(chǎn)生哪類(lèi)事件 */
    set_bit(EV_KEY, s3c_ts_dev->evbit);  /* 能夠產(chǎn)生按鍵事件 */
    set_bit(EV_ABS, s3c_ts_dev->evbit);  /* 能夠產(chǎn)生絕對(duì)位移事件 */
    /* 2.2 能產(chǎn)生這類(lèi)事件里的哪些事件 */
    set_bit(BTN_TOUCH, s3c_ts_dev->evbit); /* 能夠產(chǎn)生按鍵類(lèi)里面的觸摸屏事件 */
    input_set_abs_params(s3c_ts_dev, ABS_X, 0, 0x3FF, 0, 0);   /* X方向 0xFF是因?yàn)橛|摸屏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.注冊(cè) */
    input_register_device(s3c_ts_dev);
    /* 4.硬件相關(guān)的操作 */
    /* 4.1 使能時(shí)鐘CLKCON[15 (總開(kāi)關(guān),一般對(duì)不用的設(shè)備,時(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啟動(dòng)方式,通過(guò)讀來(lái)啟動(dòng)
     * bit[0    : 啟動(dòng)AD轉(zhuǎn)換,啟動(dòng)后會(huì)自動(dòng)清零
     */
    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
     * 使用定時(shí)器,用來(lái)解決連按或滑動(dòng)
     */
    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");




測(cè)試方法主要是檢測(cè)上報(bào)事件是否正常,要想更好的測(cè)試,需要移植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ù)實(shí)際情況來(lái)定


使用:

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

1.
修改 /etc/ts.conf第1行(去掉#號(hào)和第一個(gè)空格):
# 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語(yǔ)言 C++、JAVA、數(shù)電模電、51單片機(jī)PIC stm32 ARM Linux驅(qū)動(dòng) 嵌入式、安卓系統(tǒng) FPGADSP Cortex-M3學(xué)習(xí)

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

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

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


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

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

廠商推薦

  • Microchip視頻專(zhuān)區(qū)
  • 利用SAM E54 Xplained Pro評(píng)估工具包演示CAN轉(zhuǎn)USB橋接器以及基于CAN的主機(jī)和自舉程序應(yīng)用程序
  • 使用SAM-IoT Wx v2開(kāi)發(fā)板演示AWS IoT Core應(yīng)用程序
  • 使用Harmony3加速TCP/IP應(yīng)用的開(kāi)發(fā)培訓(xùn)教程
  • 集成高級(jí)模擬外設(shè)的PIC18F-Q71家族介紹培訓(xùn)教程
  • 貿(mào)澤電子(Mouser)專(zhuān)區(qū)
關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国内免费自拍视频 | 四虎影院网 | 美国黑人毛片 | 中国一级片在线观看 | 91天堂最新在线观看 | 国产成人永久在线播放 | 日韩免费一级毛片 | 欧美a图| 4虎 影视 免费 | 激情图片激情视频激情小说 | 欧美一区2区三区4区公司二百 | 日本卡通动漫影院网站 | 精品国产一区二区在线观看 | 91av在线国产 | 日本经典在线三级视频 | 久久频精品99香蕉国产 | 国产精品区在线12p 国产精品区一区二区三 | 女人18特级一级毛片免费视频 | 日韩精品视频观看 | 亚洲欧美自拍一区 | 在线欧美视频免费观看国产 | 人间正道是沧桑全集免费下载高清 | 欧美影片一区二区三区 | 国产免费私人影院永久免费 | 大伊香蕉精品二区视频在线 | 国产第一页在线观看 | 日韩在线一区二区三区视频 | 一二三四在线社区 | 天堂网www天堂在线资源链接 | 99在线看| 日本高清一区二区三区不卡免费 | 成人在线天堂 | 久久大胆视频 | 久久久久国产亚洲日本 | 黄色高清视频在线观看 | 自拍愉拍 | 色妞色综合久久夜夜 | 国产一级黄色大片 | 亚洲欧美日韩在线一区二区三区 | 国产日韩欧美亚洲综合在线 | 特黄特色的视频免费播放 |