7842|6

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

PIC16F690做电容式触摸按键 [复制链接]

:carnation: 

设计参考了应用笔记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[index]-(long)trip[index]))
  {
   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[index]-(long)trip[index]+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[index]=average[index]+((long)raw-(long)average[index])/16; 
  }
  //按键通道切换每10ms切换
  index=(++index)&0x03;
  CM1CON0=COMP1[index];
  CM2CON0=COMP2[index];  
  //清零寄存器为扫描下一通道准备
  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[usdata]/10000;
   a2=average[usdata]%10000/1000;
   a3=average[usdata]%1000/100;
   a4=average[usdata]%100/10;
   a5=average[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==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;
 }  
}

[ 本帖最后由 QQ175744595 于 2012-2-3 10:28 编辑 ]

showimg.jpg (167.88 KB, 下载次数: 4)

PIC16F690做电容式触摸按键

PIC16F690做电容式触摸按键

01102A_CN.pdf

487.88 KB, 下载次数: 37

售价: 1 分芯积分  [记录]

01103A_CN.pdf

510.69 KB, 下载次数: 36

售价: 1 分芯积分  [记录]

01104A_CN.pdf

346.46 KB, 下载次数: 31

售价: 1 分芯积分  [记录]

电容式触摸按键(简介).pdf

438.19 KB, 下载次数: 77

售价: 1 分芯积分  [记录]

最新回复

 感谢,学习一下不同的思路   详情 回复 发表于 2020-9-2 07:02
点赞 关注
 

回复
举报

19

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
有原理图不?
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
真棒,我好好研究研究。
 
 
 

回复

24

帖子

0

TA的资源

一粒金砂(初级)

4
 
挺好的,还是有些收获的······
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 

谢谢,谢谢大神!

 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

6
 

原理图公布一下

 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(初级)

7
 

 感谢,学习一下不同的思路

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表