英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 3764|回复: 0
打印 上一主题 下一主题

PIC16F690做电容式触摸按键【转】

[复制链接]
跳转到指定楼层
1#
发表于 2012-8-20 15:37:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
设计参考了应用笔记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;
}  
}

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

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-11-27 17:31 , Processed in 0.056463 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表