箫天 发表于 2013-3-3 12:13:51

四线电阻式触摸屏原理及MEGA8驱动

四线电阻式触摸屏原理及MEGA8驱动
(转载请注明出自http://www.avrbase.com,谢谢)
  注:本文原理部分参考并节选自《四线电阻式触摸屏控制》、《四线电阻触摸屏的工作原理》两文,作者不详,在此表示感谢。  电阻触摸屏的屏体部分是一块与显示器表面非常配合的多层复合薄膜,由一层玻璃或有机玻璃作为基层,表面涂有一层透明的导电层,上面再盖有一层外表面硬化处理、光滑防刮的塑料层,它的内表面也涂有一层透明导电层,在两层导电层之间有许多细小(小于千分之一英寸)的透明隔离点把它们隔开绝缘,如图1。http://avr.cnta.net/TouchPlane/TouchPlane.files/image002.gif图1 四线式触摸屏结构示意图
   触摸屏工作时,上下导体层相当于电阻网络,如图2所示。
            http://avr.cnta.net/TouchPlane/TouchPlane.files/image001.gif
图2 工作时的导体层   当某一层电极加上电压时,会在该网络上形成电压梯度。如有外力使得上下两层在某一点接触,则在电极未加电压的另一层可以测得接触点处的电压,从而知道接触点处的坐标。比如,在顶层的电极(X+,X-)上加上电压,则在顶层导体层上形成电压梯度,当有外力使得上下两层在某一点接触,在底层就可以测得接触点处的电压,再根据该电压与电极(X+)之间的距离关系,知道该处的X坐标。然后,将电压切换到底层电极(Y+,Y-)上,并在顶层测量接触点处的电压,从而知道Y坐标。    触摸屏与内置A/D的单片机接口可以通过4个三极管或MOS管分别给X、Y方向施加电压,并通过A/D通道读取Y、X方向的电压值来实现(见图3)。对触摸屏输入A/D的数据读取控制可采用定时查询方式和中断方式,本文采用中断方式。   http://avr.cnta.net/TouchPlane/TouchPlane.files/touch_sch.gif图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轴的坐标值。   http://avr.cnta.net/TouchPlane/TouchPlane.files/t01.jpg   http://avr.cnta.net/TouchPlane/TouchPlane.files/t03.jpg
      图4 触摸屏与驱动电路连接               图5 配合液晶屏手写显示

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

'-----------------------------------------------------------------
'name :    TouchDriver.bas
'micro:    Mega8
'compiler: Bascom-avr
'author:   slyt
'website:  http://www.avrbase.com
'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 , I As Integer
Dim Chan As Byte
Dim S1 As Single
Dim S As String * 4
Dim X As Word , Y As Word

Dim Xstr As String * 4
Dim Ystr As String * 4

On Int0 Int0_int
Enable Interrupts
Enable Int0

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

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 + 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 / 10

   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
   S = Str(x)
   Xstr = Format(s , "0000")

   Y = V2
   S = Str(y)
   Ystr = Format(s , "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://www.avrbase.com
'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% = 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
'==============================

SUB delay (dt AS SINGLE)
    T0 = Timer
    Do
        T1 = Timer - T0
    Loop Until T1 < 0 Or T1 > Dt
End Sub

sunany 发表于 2013-3-3 14:18:07

老大写的程序好规范

多啦A梦 发表于 2013-3-4 10:49:42

这个要研究下,老大好高啊!

社建电子 发表于 2013-3-4 16:47:37

可以用来测试触摸屏的好坏。

SengChuary 发表于 2013-4-10 16:55:13

不错,支持顶贴!
页: [1]
查看完整版本: 四线电阻式触摸屏原理及MEGA8驱动