role_2099 发表于 2011-3-27 14:04:08

PIC16F690做电容式触摸按键,转载

前几天在一个PIC论坛看到一篇关于PIC触摸按键的帖子,过来搜索了一下,本站还没有PIC触摸按键的帖子,所以转载过来了

-----------以下为转载内容--------------

设计参考了应用笔记AN1101-1104;

使用串口通信来读取振荡频率,通过读取没有按下和按下按键的不同频率来确定阀值。

程序运行中也可读取每个按键通道的没有触摸时的1/16平均值,通道的扫描时间为10ms循环。



配置字是,__CONFIG (0x3BC4);

#include<pic.h>
#define uchar unsigned char
#define uint unsigned int
uchar COMP1[]={0x94,0x95,0x96,0x97};//按键通道切换
uchar COMP2[]={0xa0,0xa1,0xa2,0xa3};//按键通道切换
uint average[]={0,0,0,0};//按键振荡计数平均值
uint trip[]={400,400,250,320};//按键振荡计数阀值
uchar ltmr1,htmr1;//计时器1的高8位和低8位暂存
uint raw;//16位传感器当前振荡计数值
uchar index=0; //按键标号
uchar keya,keyb,keyc,keyd; //按键状态
//-----------------------------
uchar usdata=0;//串口发送数据端口号
uchar rbuff; //接收缓存
uchar a1,a2,a3,a4,a5;
void init();//初始化配置
void usart();//串口通信
void touchkey();//按键判断
void main()
{
init();//初始化配置
while(1)
{
usart();//串口通信
touchkey();//按键判断
}
}
void interrupt intcon()
{
if((T0IF)&&(T0IE))
{
T0IF=0;
//进入中断时,10ms读取tmr1的计数值
htmr1=TMR1H; //读取计数器高8位      
ltmr1=TMR1L;//读取计数器低8位
raw=raw|htmr1;
raw=(raw<<8)|ltmr1;
// 按钮判断并置位按钮状态
if(raw<((long)average-(long)trip))
{
   switch(index)
   {
    case 0:keya=1; break;
    case 1:keyb=1; break;
    case 2:keyc=1; break;
    case 3:keyd=1; break;
    default:   break;
   }
}
// 按钮判断并置位按钮状态滞后量选200
else if(raw>((long)average-(long)trip+150))
{
   switch(index)
   {
    case 0:keya=0; break;
    case 1:keyb=0; break;
    case 2:keyc=0; break;
    case 3:keyd=0; break;
    default:   break;
   }
   //求平均值
   average=average+((long)raw-(long)average)/16;
}
//按键通道切换每10ms切换
index=(++index)&0x03;
CM1CON0=COMP1;
CM2CON0=COMP2;
//清零寄存器为扫描下一通道准备
raw=0;
ltmr1=0;
htmr1=0;
TMR0=100;
TMR1H=0;
TMR1L=0;
}
if((TMR1IF)&&(TMR1IE))
{
TMR1IF=0;
TMR1H=0;
TMR1L=0;   
}

if((RCIE)&&(RCIF))
{
rbuff=RCREG;//读取接收缓存的数据
if(OERR==1)
{
   CREN=0;
   asm("nop");
   CREN=1;
}
/*TXEN=1; //打开发送使能
TXREG=rbuff;//把接收到的数据送到发送缓存
while(!TRMT);//等待发送完成
TXEN=0; //关闭发送使能
*/
}
}
//*********初始化配置****************
void init()
{
OSCCON=0x70; //振荡器控制寄存器
GIE=1;//总中断开
PEIE=1;
//------定时器0的配置----
OPTION=0x86; //选项寄存器配置
T0IF=0;//请定时器零中断标志位
T0IE=1;//开定时器零中断
TMR0=100;
//----------------------
//------计数器1的配置--------
T1CON=0x07;
TMR1IF=0;
TMR1IE=1;
TMR1H=0;
TMR1L=0;
//---------------------------
//-------比较器的配置--------
CM1CON0=0x94;
CM2CON0=0xa0;
VRCON=0xcd;
SRCON=0xf0;
CM2CON1=0x02;
//---------------------------
//---------USART的配置-------
TXSTA=0x0c;//发送状态寄存器设置(暂时关闭要发时再开)
RCSTA=0x90;//接收状态寄存器控制
BAUDCTL=0x80;//波特率控制
SPBRG=51;//波特率9600
SPBRGH=0x00;//波特率9600
RCIE=1; //接收中断打开
TXIE=0; //发送中断关闭
//---------------------------
//-----IO口的配置-------
ANSEL=0xf2;// |设为数字IO口
ANSELH=0x00;//|
TRISA=0x22;
PORTA=0x00;
TRISB=0x20;
PORTB=0x00;
TRISC=0x0f;
PORTC=0x00;
RA0=1;
}
//**********USART**************
void usart()
{
if(rbuff==0x74)
{
//------------------------
   a1=usdata/10000;
   a2=usdata%10000/1000;
   a3=usdata%1000/100;
   a4=usdata%100/10;
   a5=usdata%10;
   a1=a1|0x30;
   a2=a2|0x30;
   a3=a3|0x30;
   a4=a4|0x30;
   a5=a5|0x30;
//------------------------

   TXEN=1; //打开发送使能
   TXREG=a1;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a2;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a3;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a4;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a5;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXEN=0; //关闭发送使能
   rbuff=0;
}
if(rbuff==0x72)
{
//------------------------
   a1=average/10000;
   a2=average%10000/1000;
   a3=average%1000/100;
   a4=average%100/10;
   a5=average%10;
   a1=a1|0x30;
   a2=a2|0x30;
   a3=a3|0x30;
   a4=a4|0x30;
   a5=a5|0x30;
//------------------------

   TXEN=1; //打开发送使能
   TXREG=a1;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a2;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a3;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a4;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a5;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXEN=0; //关闭发送使能
   rbuff=0;
}
if(rbuff==0x30)
{
usdata=0;
rbuff=0;
}
if(rbuff==0x31)
{
usdata=1;
rbuff=0;
}
if(rbuff==0x32)
{
usdata=2;
rbuff=0;
}
if(rbuff==0x33)
{
usdata=3;
rbuff=0;
}
}
//***************************
//------按键判断
void touchkey()
{
if(keya==1)
{
RA2=1;
RA4=0;
RB4=0;
RB6=1;
RC5=1;
RC6=1;
RC7=1;
}
if(keyb==1)
{
RA2=0;
RA4=0;
RB4=1;
RB6=0;
RC5=0;
RC6=1;
RC7=0;
}
if(keyc==1)
{
RA2=0;
RA4=0;
RB4=0;
RB6=0;
RC5=1;
RC6=1;
RC7=0;
}
if(keyd==1)
{
RA2=1;
RA4=0;
RB4=0;
RB6=1;
RC5=1;
RC6=0;
RC7=0;
}
}

http://cache.amobbs.com/bbs_upload782111/files_37/ourdev_625865EMIEIR.JPG
(原文件名:showimg.JPG)

点击此处下载 ourdev_625866YK5I5G.rar(文件大小:1.26M) (原文件名:电容式触摸效果视频.rar)

电容触摸传感简介ourdev_625867ABQUOQ.PDF(文件大小:409K) (原文件名:Microchip-AN1101CN.PDF)

电容触摸传感器布板和物理设计指南ourdev_625868W2B2J9.PDF(文件大小:488K) (原文件名:Microchip-AN1102CN.PDF)

电容触摸传感的软件处理ourdev_625869QUW15A.PDF(文件大小:511K) (原文件名:Microchip-AN1103CN.PDF)

配置多个电容触摸传感按钮ourdev_625870DJNUPS.PDF(文件大小:346K) (原文件名:Microchip-AN1104CN.PDF)

sangreal 发表于 2011-3-27 15:20:55

顶下

728196 发表于 2011-3-27 15:50:03

顶啊顶

GZLJZ 发表于 2011-3-27 15:54:56

顶下

surf_131 发表于 2011-3-27 23:12:56

资料不错。

不过lz查阅资料不仔细。本坛就有前几天我贴的自己摸索实现的电容触摸方案。而且,比这个程序更节省资源,更加实用。

milestone2010 发表于 2011-3-28 12:18:41

不错~MM的手也不错O(∩_∩)O哈!

role_2099 发表于 2011-3-28 16:58:45

回复【4楼】surf_131
资料不错。
不过lz查阅资料不仔细。本坛就有前几天我贴的自己摸索实现的电容触摸方案。而且,比这个程序更节省资源,更加实用。
-----------------------------------------------------------------------

这个手册是目前PIC16F690的推荐手册,因为这个只有英文版,所以我选择了把前者发过来
PS:我搜索的“触摸按键”,下次只搜索“触摸”好了

wdooy 发表于 2011-5-2 01:06:58

资料不错。标记

millwood0 发表于 2011-5-2 05:39:01

what would have been interesting is to make a spi/i2c compliant button processor out of this: when a button is pressed, the processor can send an int signal out to the mcu and the mcu would read the button. it would also be helpful for the processor to have its own configuration, settable by the mcu.

STM32_Study 发表于 2011-5-2 09:27:43

回复【8楼】millwood0
what would have been interesting is to make a spi/i2c compliant button processor out of this: when a button is pressed, the processor can send an int signal out to the mcu and the mcu would read the button. it would also be helpful for the processor to have its own configuration, settable by the mcu.

-----------------------------------------------------------------------

基本上成品的触摸IC都有这个功能

Holtek的BS80X系列

http://www.holtek.com.cn/china/products/misc_6.htm

19001579 发表于 2011-7-31 01:50:05

MARK

bowen_fang 发表于 2011-9-19 10:05:24

mark

xiaqichen 发表于 2011-9-19 10:10:12

mark 2

dy624 发表于 2011-9-20 16:48:33

mark

zou_hao1989 发表于 2011-9-21 08:36:13

回复【楼主位】role_2099
-----------------------------------------------------------------------
你用过pic16F616这个芯片做mtouch没?我之前搞51的,现在做个pic的,但之前从来没碰过pic。压力大啊

zou_hao1989 发表于 2011-10-13 21:52:57

回复【楼主位】role_2099
-----------------------------------------------------------------------

这一大段程序的主体读懂了,就是下面一小段不明白,望解释一下,thanks:
if(rbuff==0x72)
{
//------------------------
   a1=average/10000;
   a2=average%10000/1000;
   a3=average%1000/100;
   a4=average%100/10;
   a5=average%10;
   a1=a1|0x30;
   a2=a2|0x30;
   a3=a3|0x30;
   a4=a4|0x30;
   a5=a5|0x30;
//------------------------

   TXEN=1; //打开发送使能
   TXREG=a1;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a2;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a3;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a4;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXREG=a5;//把接收到的数据送到发送缓存
   while(!TRMT);//等待发送完成
   TXEN=0; //关闭发送使能
   rbuff=0;
}
if(rbuff==0x30)
{
usdata=0;
rbuff=0;
}
if(rbuff==0x31)
{
usdata=1;
rbuff=0;
}
if(rbuff==0x32)
{
usdata=2;
rbuff=0;
}
if(rbuff==0x33)
{
usdata=3;
rbuff=0;
}
}

zou_hao1989 发表于 2011-10-13 21:55:28

回复【6楼】role_2099
-----------------------------------------------------------------------

还有有些触摸按钮算法可以不用串口通信来读取震荡频率,而是直接通过Timer0和Timer1来判断,两者有什么区别?

role_2099 发表于 2011-10-13 22:16:53

回复【14楼】zou_hao1989
回复【楼主位】role_2099
-----------------------------------------------------------------------
你用过pic16f616这个芯片做mtouch没?我之前搞51的,现在做个pic的,但之前从来没碰过pic。压力大啊
-----------------------------------------------------------------------

呵呵,我是光说不练嘴把式啊,这个帖子是我转的,自己并没有做出来。争取这个周末弄一弄,仿制一下

zyw19987 发表于 2011-10-14 14:09:48

PIC16F690触摸按键

leexiaowei 发表于 2011-10-24 21:55:52

不过lz查阅资料不仔细。本坛就有前几天我贴的自己摸索实现的电容触摸方案。而且,比这个程序更节省资源,更加实用。

tlflzs 发表于 2011-11-28 21:23:11

参考,参考,有价值

jlian168 发表于 2013-1-9 15:48:04

surf_131 发表于 2011-3-27 23:12 static/image/common/back.gif
资料不错。

不过lz查阅资料不仔细。本坛就有前几天我贴的自己摸索实现的电容触摸方案。而且,比这个程序更 ...

Sir:

Where is it?

Thank you.

Seaber 发表于 2013-2-15 22:37:07

mark
                                 

aaronhuang 发表于 2013-6-6 00:50:57

PIC16F886做电容触摸

lang6027 发表于 2013-6-13 16:16:21

PIC16F690在单火线上边有见过做触控还有RF接收,功耗做的很低,手湿触控也还能用,不知道这个程序能不能支持手湿的情况

segeal 发表于 2013-6-17 14:34:29

{:lol:}mark 一下下

蓦然回首; 发表于 2013-12-12 17:56:51

问一下各位大侠,那个T0是不是自动重装啊,只看到他初始化中赋了一下值啊?
“T0IF=0;//请定时器零中断标志位
T0IE=1;//开定时器零中断
TMR0=100;”

蓦然回首; 发表于 2013-12-13 18:15:51

没仔细看

home 发表于 2013-12-26 10:01:35

非常好,学习了!

zhiguangqi 发表于 2013-12-27 08:44:17

很好,谢谢

lcl4518 发表于 2013-12-27 09:07:29

不错不错!!标记一下,学习了

waothom 发表于 2014-5-5 14:24:07

顶下,pic触摸按键已经没什么了

pan90 发表于 2014-5-5 18:38:33

mark {:lol:}{:lol:}{:lol:}

micheal147 发表于 2015-3-11 11:52:50

mark {:lol:}{:lol:}

五号电池 发表于 2015-5-22 21:31:44

顶下!!!!!!

freeboyxd 发表于 2015-5-22 21:59:43

没用过PIC,支持

五号电池 发表于 2015-6-1 22:35:36

顶一个!!!!!

moen 发表于 2015-6-2 13:37:40

不错,参考

ZYBing 发表于 2016-3-10 19:42:09

mark,谢谢!
页: [1]
查看完整版本: PIC16F690做电容式触摸按键,转载