基于
51
单片机自制触摸屏
基于51单片机自制触摸屏
电容触摸研究
上一期我们聊到触摸技术的实现,
触摸式的电子琴½有没有制½出来呢?½又有没有参考源
程序来学习触摸式琴键的编程技巧呢?如果有,
½会得到更深入的启发。
实际上用单片机实现电
平式触摸的原理是简单的,因为手指触摸即有电平的变化,读出电平状态就可以处理按键了。
与
之相比,
看上去更高级一些的电容式触摸技术就没有这么简单了,
所谓的“更高级”并不是因为
它的技术实现复杂,
还是指在应用上显得更文雅。
电容式触摸技术可以让手指不接触到金属导线,
给用户的感觉是更安全的。
因为谁也不½保证裸露在外的金属片会不会带有上千伏的电压。
电容
式触摸技术的另一个优势是在产品设计方面。对于我们电子爱½者来说,找到一款适合自己 DIY
½品的外壳是很困难的,
有的外壳制½高手可以在很短的时间内制½出精致又专业的外壳,
可是
并不是每个人½有这样的本领。
为露出微动开关而在外壳上钻孔是再平常不过的了,
可是钻了孔
就很难美观了,我也一时为这个问题困惑。幸½有电容式触摸技术,可以把我们的触摸片设计在
塑料外壳的内部(外壳不½是金属的,不然电容触摸就没有效果了)
,外壳的表面只要贴一张标
签,写明这是触摸按键,具有什么功½就可以了。
电容式触摸技术这么½,
在哪里可以得到呢?上一期我也有讲过,
现在市场有专业的电容式
触摸芯片,芯片厂商已经把电容式触摸的处理集成到芯片中。这种芯片的½处就是稳定性½,
不
需要二次开发就可以直接½用。芯片上½会留有各种接口,或与单片机连接或驱动控制电路。
缺
点是价格太高而且不易买到,与触摸芯片的½处相比,缺点½像是致½的。如果不½在一般的电
子市场里买到,或者一片4键触摸芯片要花30块钱购买,那么又会有多少爱½者朋友真的可以½
松拥有呢?那么,
½不½有更½的替代方案,
我们可不可以用其他方法实现电容式触摸操½呢?
为了用单片机实现精简电路的电容式触摸操½,我是下了不少功夫的。结果很让我满意,
心
血没有½费。首先我研究了一下电容式触摸技术的实现原理。因为我需要从原理角度入手,看看
在同一原理的情况下有没有什么方法可以用单片机模拟触摸芯片。
上一期我们也简单地介绍过电
容式触摸技术的原理,
其实就是利用了电容通交流阻直流的特性,
把手指和触摸片½成电容器的
两个极片,手指和触摸片之间的绝缘材料就是电容器中的隔离介质。对了,另外还需要一个交流
信号源的接触片,让它与信号输入的触摸片平行放½。½手指按到触摸区域时,一个交流回路就
½成了。
触摸片输入端可以收到与交流信号源相同的信号,
这一信号的特性随着手指触摸面积和
绝缘介质的厚度和材质而变化。
看到这一原理,
我闭上眼睛,
用想象力构建一个单片机实验平台,
用 PWM 功½产生交流信号,
再用 ADC 功½½为触摸片输入端的信号读取,
用给单片机下½½的 RS232
串口和串口助手½件在电脑上显示出 ADC 接收到的数据。
嗯,这个想法是可行的,于是我开始行动,把想象的实验用实际的电路组建。这次依然½用了
我所熟悉的
STC
单片机,STC12C5A60S2具有2路
PWM
输出和8路10½
ADC
功½,完全可以满
足我的实验需要。电脑上直接用
STC-ISP
½件自带的串口帮助½件就可以显示十六进制的数据
了。我在自己的½站里找到
ADC
和
PWM
功½的编程模板,新建立一个
KEIL
工程,开始移植
模板、设计程序。程序很简单,就是一直读取
ADC
输入引脚的数据,从0×00到0×FF 之间即表
示0V 到5V 的电压值。PWM 输出38kHz 的方波信号,占空比调整到50%。硬件电路方面则是用
了两片金属片½触摸片,一片连接到
PWM
输出引脚,另一片连接到
ADC
输入引脚,两个触摸
片½量靠近½不½碰上。绝缘介质没有精心选择,只是找到一张名片,这是目前可以找到的最½
材料了。连接用的是普通的导线,先不去考虑外来的干扰问题。
一切就绪,开始实验。接通电源,单片机开始工½,串口助手的接收窗口不断显示出
ADC
的读数。在没有手指按压的时候,ADC 的读数范围是在0×20到0x70之间,数据的变化看上去没
有规律。可是½我的手指按在名片上的时候,特别是靠近
ADC
输入端触摸片的时候,ADC 的读
数是在0×10和0×FF 之间有规律地跳变,不过跳变的频率并不快。这一实验结果给了我信心,我
又继续实验,用手掌触摸、拿开名片直接接触触摸片、把名片换成玻璃片、用手触摸导线、用手
触摸单片机的引脚,把每一项实验的结果记½下来,感觉成功离我不远了。PWM 输出½像是必
须的内容,不然没有交流信号源,也就不½产生电容回路了。那么我改变
PWM
的频率,ADC
的读数会不会也随之变化呢?于是我把用
PWM
功½实现的交流输出改成了用
I/O
接口模拟,因
为这样一来,在程序上更容易控制输出方波的频率。我试着把频率从1Hz 开始慢慢调整到1kHz,
在此过程中不断地用手指触摸,看看
ADC
读数有什么变化。结果证明,变化是有的,可是不明
显,任凭方波频率怎么变换,ADC 读数一直在一个固有频率周围徘徊。于是我试着关上方波输
出,
看看
ADC
读数的固有频率是不是来自方波以外的什么东西。
果然,
关掉交流信号输出,
ADC
还是可以读到固有频率的数据,在0×10和0×FF 之间交替。½拿开名片直接触摸
ADC
输入引脚
时,0×10还会变成0×00,也就是0V。这一结果让我兴奋,因为不需要交流信号源也可以读到一
定频率的
ADC
交流数据,可是这一频率又是哪里来的呢?这个问题一直困扰着我,因为急于想
实现单片机精简电容式触摸技术,所以就没有花时间认真研究这一频率的来历。可½是50Hz 的
市电频率在人½上的干扰,
或是人½自带的杂波电流独有频率。
我又考虑到这种频率会不会是我
实验场地这里特有的什么干扰,
于是我又去了另外一些地方做同样的实验,
结果证明并不是实验
场地的问题,这一频率依然是一个未经探索的秘密。
单片机实现电容式触摸开关
电容式触摸开关实验电路原理图
对固有频率的无知并不½响制½电容式触摸操½,
这是让我很开心的事情,
不然我还需要做
一大堆实验来深入研究下去。
½然,
我以后会研究的,
只是现在我最有兴趣的是实现电容式触摸。
½的,我们整理一下思路。现在我们通过实验得到了这样的结果,硬件电路上只需要一个触摸金
属片连接到单片机的
ADC
输入引脚,手指隔着名片触摸操½时,ADC 的读数会在0×10和0×FF
之间以一定的频率交替变化,
在没有手指触摸时,ADC 的读数会在0×20和0×70之间交替变化。这些数据可½在环境不同时有
所不同,½不变的是½手指触摸时
ADC
读数的变化数值会比没有触摸时大。有了这一项实验现
象½为支点,我们接下来要做的就是用单片机处理
ADC
读数,判断数值变化的规律,从而得知
是否有触发。编程并不难,每个人½可以有自己的数值处理方式。下面给出一段我编写的电容式
触摸按键的源程序,大家可以参考,½这并不是唯一的处理方式,还会有更½的方法等着½去发
现呢。
“电容式触摸开关实验”是我制½的一款简单的触摸开关,在单片机的
P1.7接口上接一个
LED,½用连接在 P1.0接口上的触摸片来控制 LED
的亮或灭。½可以直接制½这个触摸开关,
以此了解电容式触摸的性½。½然,这也是一个很½的实例,参考电路原理图和源程序就可以了
解其工½原理。
只要在源程序上稍微修改就可以制½属于½自己的电容式触摸½品了。
在制½电
容式触摸操½½品的时候需要注意一些问题,
这些问题并不是从什么专业机构找来的资料,
而是
我通过实验总结出来的经验,仅供大家参考。另外,对于没有交流信号源参与的电路是否可靠我
还没有研究,这一制½是在我的几个实验环境下完成的,并不½表示在½的环境里也可以实现。
本文介绍的电容式触摸技术仅算是抛砖引玉,
也是大家和我一起共同验证的过程,
看看我还有哪
些没有考虑周全的地方。
欢迎读者朋友把½的想法和建议与我交流,
我真的很希望和大家一起把
这项技术改进到和专业的触摸芯片媲美。
注意事项:
◆
ADC
读数和
ADC
½数、采集速度具有一定关系。
◆ ½用电池供电和½用市电供电时
ADC
的读数也有区别。
◆ ½用电池供电时电容式触摸的灵敏度较市电供电时½。
◆ 不用绝缘介质下
ADC
读数变化有所不同。
◆ 连接
ADC
输入端的触摸片的面积也会½响电容式触摸的灵敏度。
◆
ADC
读数只是在某一个数值的区间,为了判断可靠,需要设计防误判程序。
细心的朋友可½注意到了,我在源程序中
ADC
读数部分加入了防误判程序,实践证明这
是非常有必要的。其实防误判程序就是通过连续多次读取
ADC
数值,然后把多次读到的结果进
行对比。如果有外部干扰或是
ADC
读数错误,在这个对比的过程中就会被发现,即达到防干扰、
防误判的½用。电容式触摸开关实验的源程序文件请到《无线电》杂志½站上下½½。
防误判部分源程序
/******************************************************************************
½数名:触摸按键处理½数
调 用:?
= Read_R ();
参 数:无
返回值:bit
1表示有感应物,0表示没有感应物
结
备
果:
注:需要根据实现应用调协灵敏度和其他参数
/*****************************************************************************/
bit Read_R (void){
unsigned char R,ii,m=0,i,j,k;
bit aa;
for(ii=0;ii<3;ii++){ //循环检查防干扰
j=0;k=0;
for(i=0;i<10;i++){ //一次采集数据的数量
DELAY_MS (3); //3毫秒延时
R = Read (0); //ADC
读取数据
if(R < 0x2F){ //此参数可调整感应灵敏度值在0x01到0x2F
k++; //波谷计数加1
}
if(R == 0xFF){ //ADC
读数的最大值必须等于0xFF
j++; //波峰计数加1
}
}
if(k>1 && j>1){ //触摸波½的数量积加 m
的值
m++;
}else{
m=0; //如果波½条件不符合则 m=0
}
评论