1、51 单片机系统中的触摸屏坐标算法引 言:人机对话的界面种类有很多,比如显示器、LED、LCD 及带触摸屏的 LCD 等。其中后者是最近几年刚发展起来的一项新技术,它通过计算机技术处理声音、图像、视频、文字、动画等信息,并在这些信息间建立一定的逻辑关系,使之成为能交互地进行信息存取和输出的集成系统。换而言之,它能综合信息发布者的意愿和接受者对信息的需求及接受习惯,对信息进行收集、加工、整合并双向式传播。触摸屏系统符合简便、经济、高效的原则,具有人机交互性好、 操作简单灵活、输入速度快等特点。它与迅猛发展的计算机网络和多媒体技术相结合,使用者仅仅用手指触摸屏幕,就能进行信息检索、数据分析,甚至可
2、以做出身临其境、栩栩如生的效果;较键盘输入简单、直观、快捷,具有丰富多采的表现能力,比以往任何传媒更具亲合力。 触摸屏和 51 单片机接口,可以使一些小系统的操作更加方便、快捷。使用触摸屏时最重要的问题是确定坐标位置,即确定触点位置是否在该键的有效区域之内。由于 51 系列单片机的汇编语言不具备其它高级语言所具有的丰富库函数及逻辑运算能力,所以如何用 51单片机简捷准确地完成这一任务,便成为应用中迫切需要解决的问题。在实际应用中,我们采用了 ADS7843 作为触摸屏的控制器。关于 ADS7843 的原理及工作方式,已经有很多文章发表,而如何确认坐标位置却很少提及。本文仅就坐标确定问题做如下分
3、析。1 转换模式ADS7843 的转换精度有 8 位和 12 位两种,可以精确到 X 或 Y 方向上的 1/256 和1/4096。我们采用清华蓬远公司的 PDA240160 触摸显示屏,外形尺寸是61.6mm42.4mm,所以没必要采用 12 位 A/D 转换,而只需要 8 位 A/D 转换就足以达到所需精度,即最小分度是 X、Y 长度方向的 1/256。2 坐标确定PDA240160 触摸显示屏的坐标如图 1。其中,(X,Y)是一个图表按键的中心坐标,(X,Y)是右下角坐标,(X”,Y”)是其左上角的坐标。在触及屏幕时,触点只要在(X,Y)和(X”,Y”)矩形区域内均认为是触摸该键有效。假
4、设一个 3232 点阵的图标按键中心坐标(X,Y)为(50,50),那么(X,Y)就是( 35,40),(X”,Y”)就是(65,60)。在触摸时只要得到的键坐标在(X,Y)和(X”,Y”)之间,即认为是触摸到了该键。而在该键坐标范围内的值又是如此之多,如何来处理得到的坐标呢?最初我们采取散转方式,结果是程序太冗长、可读性差且可移植性不好,不能作为子程序来调用。经过探讨分析,我们最后采取了查表的方式。首先,制作如下所示的坐标表(包含当前屏幕上的所有键的两个角坐标):表中每一行均代表一个键值的两个角坐标(需要放置完图标按键后调用相关程序确定两个角的坐标值),最后的字符 001n 是每个键值的标志
5、(简写 A)。这个标志很有用,在以后的程序中会看到。3 程序流程图与程序清单程序流程图如图 2 。子程序清单见本刊网络补充版( )。其中 XA、YA 存储的是 A/D 转换后的坐标值。程序已经调试通过,敬请读者验证。结 语经过反复测试后得出:每个触摸键的反应都很灵敏,而且在每个图标键的有效区域内都能反应。证明这个思路简捷、易懂、可移植性好,在确定触摸按键位置坐标时是非常具有实际应用价值的。*文件名 Touch.c功 能 8051 单片机驱动 ADS7846/ADS7843 芯片简 介 ADS7846/7843 芯片 适合用在 4 线制触摸屏,它通过标准 SPI 协议和 CPU 通信,操作简单,
6、精度高,当触摸屏被按下时(即有触摸事件发生)则 ADS7846 向 CPU 发中断请求,CPU 接到请求后,应延时一下再响应其请求,目的是为了消除抖动使得采样更准确。如果一次采样不准确,可以尝试多次采样取最后一次结果为准,目的也是为了消除抖动。原作者 鞠春阳版 本 v1.8最后修改时间 2004 年 6 月 23 日 下午版 权 哈尔滨众邦龙科技开发有限公司 单片机坐标网: */ #include “reg51.h“#include “intrins.h“sbit DCLK=P16; /根据用户自己的定义sbit CS=P22;sbit DIN=P23;sbit DOUT=P24;sbit B
7、USY=P25;delay(unsigned char i-)while(i-);void start() /SPI 开始DCLK=0;CS=1;DIN=1;DCLK=1;CS=0;WriteCharTo7843(unsigned char num) /SPI 写数据unsigned char count=0;DCLK=0;for(count=0;count8;count+)num=1;DIN=CY;DCLK=0; _nop_();_nop_();_nop_(); /上升沿有效DCLK=1; _nop_();_nop_();_nop_();ReadFromCharFrom7843() /SPI
8、 读数据unsigned char count=0;unsigned int Num=0;for(count=0;count12;count+)Num=1;DCLK=1; _nop_();_nop_();_nop_(); /下降沿有效DCLK=0; _nop_();_nop_();_nop_();if(DOUT) Num+;return(Num);void ZhongDuan() interrupt 0 /外部中断 0 用来接受键盘发来的数据unsigned int X=0,Y=0;delay(10000); /中断后延时以消除抖动,使得采样数据更准确start(); /启动 SPI/ whi
9、le(BUSY); /如果 BUSY 信号不好使可以删除不用delay(2);WriteCharTo7843(0x90); /送控制字 10010000 即用差分方式读 X 坐标 详细请见有关资料/ while(BUSY); /如果 BUSY 信号不好使可以删除不用delay(2);DCLK=1; _nop_();_nop_();_nop_();_nop_();DCLK=0; _nop_();_nop_();_nop_();_nop_();X=ReadFromCharFrom7843(); /读 X 轴坐标WriteCharTo7843(0xD0); /送控制字 11010000 即用差分方式读 Y 坐标 详细请见有关资料DCLK=1; _nop_();_nop_();_nop_();_nop_();DCLK=0; _nop_();_nop_();_nop_();_nop_();Y=ReadFromCharFrom7843(); /读 Y 轴坐标CS=1;main()TMOD=0x11; / 记数器 0 计数器 1 都以 16 位 记数TCON=0x00;IE=0x83; /1000 0001 EA=1 中断允许,IP=0x01;while(1);/等待触摸中断