首页


四线电阻式触摸屏原理及MEGA8驱动
(转载请注明出自http://avr.cnta.net,谢谢)

  注:本文原理部分参考并节选自《四线电阻式触摸屏控制》、《四线电阻触摸屏的工作原理》两文,作者不详,在此表示感谢。

  电阻触摸屏的屏体部分是一块与显示器表面非常配合的多层复合薄膜,由一层玻璃或有机玻璃作为基层,表面涂有一层透明的导电层,上面再盖有一层外表面硬化处理、光滑防刮的塑料层,它的内表面也涂有一层透明导电层,在两层导电层之间有许多细小(小于千分之一英寸)的透明隔离点把它们隔开绝缘,如图1。

图1 四线式触摸屏结构示意图
 

  触摸屏工作时,上下导体层相当于电阻网络,如图2所示。

图2 工作时的导体层

 

  当某一层电极加上电压时,会在该网络上形成电压梯度。如有外力使得上下两层在某一点接触,则在电极未加电压的另一层可以测得接触点处的电压,从而知道接触点处的坐标。比如,在顶层的电极(X+,X-)上加上电压,则在顶层导体层上形成电压梯度,当有外力使得上下两层在某一点接触,在底层就可以测得接触点处的电压,再根据该电压与电极(X+)之间的距离关系,知道该处的X坐标。然后,将电压切换到底层电极(Y+,Y-)上,并在顶层测量接触点处的电压,从而知道Y坐标。  

  触摸与内置A/D的单片机接口可以通过4个三极管或MOS管分别给X、Y方向施加电压,并通过A/D通道读取Y、X方向的电压值来实现(见图3)。对触摸屏输入A/D的数据读取控制可采用定时查询方式和中断方式,本文采用中断方式。

3 四线电阻式触摸屏与MEGA8的接口电路

 

  在触摸屏不处于触摸状态时MCU 使Q1、Q3、Q4截止,Q2导通(MCU控制口PE2为“1”)。一旦出现触摸动作,触摸屏经由D1产生一个中断信号(PE5),MCU立即使Q3导通,在Y方向上形成电流回路,启动MCU A/D转换—ADC0通道,由X+即可读出Y轴的坐标值;同样MCU关闭Q2、Q3,打开Q1、Q4,启动MCU A/D转换—ADC1通道由Y+即可读出X轴的坐标值。

  

图4 触摸屏与驱动电路连接               图5 配合液晶屏手写显示

 

  MEGA8驱动程序使用BASCOM-AVR编写,串口输出数据。触摸屏XY连线及方向与电路图稍有不同,程序仅供参考。

'-----------------------------------------------------------------
'name :    T
ouchDriver.bas
'micro:    Mega8

'compiler: Bascom-avr

'author:   slyt

'website:  http://avr.cnta.net
'date:     2009-09-10
'-----------------------------------------------------------------

$regfile = "m8def.dat"

$crystal = 4000000

$baud = 9600

$hwstack = 32

$swstack = 32

$framesize = 40

 

Config Adc = Single , Prescaler = Auto , Reference = Internal

 

Ddrb = &HFF

Ddrd.6 = 1

Ddrd.2 = 0

 

Portb = &B11100

Portd = &HFF

 

Dim V1 As Word , V2 As Word

Dim X As Word , Y As Word

Dim Xstr As String * 4

Dim Ystr As String * 4

 

Pe1 Alias Portb.1

Pe2 Alias Portb.2

Pe3 Alias Portb.3

Pe4 Alias Portb.4

Pe5 Alias Portd.2

Pe6 Alias Portd.6

 

Osccal = &HA0

 

On Int0 Int0_int

Enable Interrupts

Enable Int0

 

Start Adc

 

Do

    Idle

Loop

 

Int0_int:

   Pe5 = 0 : Pe6 = 0

   Pe3 = 0 : Pe2 = 1                         'X轴加电压

   Pe4 = 1 : Pe1 = 0

   V1 = Getadc(0)                            'ADC0,取X电压

   V1 = V1 + Getadc(0)                       'ADC0,取X电压

   V1 = V1 + Getadc(0)                       'ADC0,取X电压

   V1 = V1 + Getadc(0)                       'ADC0,取X电压

   V1 = V1 + Getadc(0)                       'ADC0,取X电压

   V1 = V1 / 5

 

   Pe3 = 1 : Pe2 = 0                         '关闭X轴电压及接地

   Pe4 = 0 : Pe1 = 1                         'Y轴加电压

   V2 = Getadc(1)                            'ADC1,取Y电压

   V2 = V2 + Getadc(1)                       'ADC1,取Y电压

   V2 = V2 + Getadc(1)                       'ADC1,取Y电压

   V2 = V2 + Getadc(1)                       'ADC1,取Y电压

   V2 = V2 + Getadc(1)                       'ADC1,取Y电压

   V2 = V2 / 5

 

   X = 1023 - V1

   Xstr = Str(x)

   Xstr = Format(Xstr , "0000")

 

   Y = V2

   Ystr = Str(y)

   Ystr = Format(Ystr , "0000")

 

   Portb = &B11100

   Pe5 = 1

   Pe6 = 1

 

   Print Xstr ; Ystr

Return
 

 

  PC演示程序使用Quick Basic编写,演示屏幕触摸画点、触摸屏和液晶屏坐标位置关联定位。

'-----------------------------------------------------------------
'name :    TFT_Touch.bas
'compiler: Quick Basic

'author:   slyt

'website:  http://avr.cnta.net
'date:     2009-09-10
'-----------------------------------------------------------------

DECLARE SUB delay (dt AS SINGLE)

SCREEN 12

CLS

CLEAR

 

OPEN "COM1:9600,N,8,1,BIN" FOR INPUT AS #1

 

ON COM(1) GOSUB COM1HANDDLE

COM(1) OFF

COM(1) ON

 

DIM x AS INTEGER

DIM y AS INTEGER

DIM a(4) AS INTEGER

DIM b(4) AS INTEGER

DIM aa(4) AS INTEGER

DIM bb(4) AS INTEGER

DIM intrun AS INTEGER

 

'调入屏幕坐标与触摸屏值换算参数

OPEN "para.ini" FOR INPUT AS #2

    LINE INPUT #2, para$

    kx = VAL(para$)

    LINE INPUT #2, para$

    ky = VAL(para$)

    LINE INPUT #2, para$

    dx = VAL(para$)

    LINE INPUT #2, para$

    dy = VAL(para$)

CLOSE #2

 

DO

    ak$ = INKEY$

    ak$ = UCASE$(ak$)

    SELECT CASE ak$

        CASE " "

            CLS

        CASE CHR$(27)

            SCREEN 0

            END

 

        CASE "C"          '校正坐标转换参数,在屏幕角依次显示十字

            a(1) = 10: b(1) = 10

            a(2) = 10: b(2) = 460

            a(3) = 630: b(3) = 10

            a(4) = 630: b(4) = 460

            LOCATE 5, 1

            FOR i = 1 TO 4

                LINE (a(i) - 10, b(i))-(a(i) + 10, b(i)), 15

                LINE (a(i), b(i) - 10)-(a(i), b(i) + 10), 15

                intrun = 0

                DO

                LOOP UNTIL intrun = 1

                aa(i) = x: bb(i) = y

                SOUND 1200, 1

                PRINT i, x, y

                delay .5

                inrun = 0

                COM(1) OFF

                delay .5

                LINE (a(i) - 10, b(i))-(a(i) + 10, b(i)), 0

                LINE (a(i), b(i) - 10)-(a(i), b(i) + 10), 0

                COM(1) ON

            NEXT

            CLS

            '换算参数

            daa = (aa(3) + aa(4) - aa(1) - aa(2)) / 2

            dbb = (bb(2) + bb(4) - bb(1) - bb(3)) / 2

            da = a(3) - a(1)

            db = b(2) - b(1)

            kx = da / daa

            ky = db / dbb

            dx = a(1) - kx * (aa(1) + aa(2)) / 2

            dx = dx + a(3) - kx * (aa(3) + aa(4)) / 2

            dx = dx / 2

            dy = b(1) - ky * (bb(1) + bb(3)) / 2

            dy = dy + b(2) - ky * (bb(2) + bb(4)) / 2

            dy = dy / 2

            '存储参数

            OPEN "para.ini" FOR OUTPUT AS #2

                PRINT #2, STR$(kx)

                PRINT #2, STR$(ky)

                PRINT #2, STR$(dx)

                PRINT #2, STR$(dy)

            CLOSE #2

            intrun = 0

 

        CASE ELSE              '在触摸位置画圆点

            IF intrun = 1 THEN

                intrun = 0

                px = kx * x + dx

                py = ky * y + dy

                'colr% = CINT(RND * 15)

                colr% = 15

                CIRCLE (px, py), 3, colr%

                PAINT (px, py), colr%

            END IF

    END SELECT

   

LOOP UNTIL ak$ = CHR$(27)

END

 

 

'串口接收中断服务程序

COM1HANDDLE:

    intrun = 1

    COM(1) OFF

    LINE INPUT #1, dz$

    dz$ = RIGHT$(dz$, 8)

    xy$ = LEFT$(dz$, 4)

    x = VAL(xy$)

    xy$ = RIGHT$(dz$, 4)

    y = VAL(xy$)

    COM(1) ON

RETURN

 

END

 

SUB delay (dt AS SINGLE)

    t0 = TIMER

    DO

        t1 = TIMER - t0

    LOOP UNTIL t1 < 0 OR t1 > dt

END SUB


 

 goto1480@163.com