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

2020-02-06 10:06发布

前几天在一个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[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;
}  
}


(原文件名: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)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
38条回答
wdooy
1楼-- · 2020-02-07 09:37
资料不错。  标记
millwood0
2楼-- · 2020-02-07 14:45
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
3楼-- · 2020-02-07 17:05
 精彩回答 2  元偷偷看……
19001579
4楼-- · 2020-02-07 20:54
MARK
bowen_fang
5楼-- · 2020-02-07 23:03
mark
xiaqichen
6楼-- · 2020-02-08 01:30
mark 2

一周热门 更多>