|
数据手册和 ATmel Demo板资料:点击此处下载 ourdev_680693VN2ZYL.zip(文件大小:1.46M) (原文件名:qt60xxx_designs.zip)
我现正在使用这颗芯片做项目,本来打算使用ATmel提供QTouch库直接做在主控芯片里,后来经过评估发现MCU的资源还是太少了点,我要做12个按键由其是IO不够。后来改成了这颗固定芯片的方案。其实这颗芯片还是很好用的,可以通过IIC接口和主控芯片连结,QT60160的change引脚接到主控芯片的外部中断引脚上,只要有键被触摸change引脚就会产生一个高电平触发MCU,然后MCU读走键值后change又会回到低电平。整个芯片基本上不要做做太多的配置,你只要根据你的面板厚度配置好每个键的触摸阀值就好。
上部分源码:
/************************************************
文件:TWI.c
用途:TWI操作函数
注意:
************************************************/
//器件地址格式: 0 0 1 0 0 0 1 R/W 即(17+R/W位)
#define W_ADD 0x22 //写从地址
#define R_ADD 0x23 //读从地址
#define SLAW 0x18
#define ERR_SLAW 1
//-----函数声明-----------------------------------
void i2cstart(void);
uchar i2cwt(uchar data);
uchar i2crd(void);
void i2cstop(void);
void WriteQT(uchar mem_add,uchar con_dat);
uchar Read_key(void);
uchar key_switch(uchar key_num);
///////////////////////////////////////////////////////////////////////
// Qt60160初始化
///////////////////////////////////////////////////////////////////////
void Init_Qt60160(void)
{
uchar temp;
WriteQT(130,0x55);//配置解锁
WriteQT(179,0x52);//启用0键
WriteQT(180,0x52);//启用1键
WriteQT(181,0x52);//启用2键
WriteQT(182,0x52);//启用3键
WriteQT(183,0x52);//启用4键
WriteQT(184,0x52);//启用5键
WriteQT(185,0x52);//启用6键
WriteQT(186,0x52);//启用7键
WriteQT(187,0x52);//启用8键
WriteQT(188,0x52);//启用9键
WriteQT(189,0x52);//启用10键
WriteQT(190,0x52);//启用11键
WriteQT(191,0x00);//禁用12键
WriteQT(192,0x00);//禁用13键
WriteQT(193,0x00);//禁用14键
WriteQT(194,0x00);//禁用15键
//------设置阀值------------------------------
WriteQT(131,0xa3);//启用0键 NTHR=3,NDRIFT=10
WriteQT(132,0xa3);//启用1键
WriteQT(133,0xa3);//启用2键
WriteQT(134,0xa3);//启用3键
WriteQT(135,0xa3);//启用4键
WriteQT(136,0xa3);//启用5键
WriteQT(137,0xa3);//启用6键
WriteQT(138,0xa3);//启用7键
WriteQT(139,0xa3);//启用8键
WriteQT(140,0xa3);//启用9键
WriteQT(141,0xa3);//启用10键
WriteQT(142,0xa3);//启用11键
//------------------------------------
WriteQT(251,3);//awake
WriteQT(252,25);//awake
WriteQT(253,10);//awake
WriteQT(125,0x55);//Recalibrate All
}
///////////////////////////////////////////////////////////////////////
// 开关按键通道
///////////////////////////////////////////////////////////////////////
void switch_key(uchar contl)
{
uchar temp;
WriteQT(130,0x55);//配置解锁.
NOP();NOP();NOP();NOP();
NOP();NOP();NOP();NOP();
if(contl)
{
WriteQT(179,0x52);//启用0键
NOP();
WriteQT(180,0x52);//启用1键
NOP();
WriteQT(181,0x52);//启用2键
NOP();
WriteQT(182,0x52);//启用3键
NOP();
WriteQT(183,0x52);//启用4键
NOP();
WriteQT(184,0x52);//启用5键
NOP();
WriteQT(185,0x52);//启用6键
NOP();
WriteQT(186,0x52);//启用7键
NOP();
WriteQT(187,0x52);//启用8键
NOP();
WriteQT(188,0x52);//启用9键
NOP();
WriteQT(189,0x52);//启用10键
NOP();
WriteQT(190,0x52);//启用11键
NOP();
WriteQT(191,0x00);//禁用12键
NOP();
WriteQT(192,0x00);//禁用13键
NOP();
WriteQT(193,0x00);//禁用14键
NOP();
WriteQT(194,0x00);//禁用15键
}
else
{
WriteQT(179,0x00);//禁用0键
NOP();
WriteQT(180,0x00);//禁用1键
NOP();
WriteQT(181,0x00);//禁用2键
NOP();
WriteQT(182,0x52);//启用3键------------------------
NOP();
WriteQT(183,0x00);//禁用4键
NOP();
WriteQT(184,0x00);//禁用5键
NOP();
WriteQT(185,0x00);//禁用6键
NOP();
WriteQT(186,0x00);//禁用7键
NOP();
WriteQT(187,0x00);//禁用8键
NOP();
WriteQT(188,0x00);//禁用9键
NOP();
WriteQT(189,0x00);//禁用10键
NOP();
WriteQT(190,0x00);//禁用11键
NOP();
WriteQT(191,0x00);//禁用12键
NOP();
WriteQT(192,0x00);//禁用13键
NOP();
WriteQT(193,0x00);//禁用14键
NOP();
WriteQT(194,0x00);//禁用15键
}
temp=Read_key();//读取键值
//WriteQT(125,0x55);//Recalibrate All
}
/*************************************************************************
** 函数名称: i2cstart(void)
** 功能描述: i2c通信开始
**************************************************************************/
void i2cstart(void)
{
uint temp;
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
temp=0;
while (!(TWCR & (1<<TWINT)))
{
if((++temp)>6000)
break;
}
}
/*************************************************************************
** 函数名称: unsigned char i2cwt(unsigned char data)
** 功能描述: i2c写数据,返回TWI状态
** 输 入:
** 输 出: TWI状态
**************************************************************************/
uchar i2cwt(uchar data)
{
uint temp;
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
temp=0;
while (!(TWCR & (1<<TWINT)))
{
if((++temp)>6000)
break;
}
return(TWSR&0b11111000);
}
/*************************************************************************
** 函数名称: unsigned char i2crd(void)
** 功能描述: i2c读数据
** 输 入:
** 输出 : 读取的数据
**************************************************************************/
uchar i2crd(void)
{
uint temp;
TWCR= (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
temp=0;
while (!(TWCR & (1<<TWINT)))
{
if((++temp)>6000)
break;
}
return(TWDR);
}
/*************************************************************************
** 函数名称: i2cstop(void)
** 功能描述: i2c停止
**************************************************************************/
void i2cstop(void)
{
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
/*************************************************************************
** 函数名称: WriteQT(uchar mem_add,uchar con_dat) //写数据程序
** 功能描述: 向QT60160写入配置数据
** 输 入 unsigned mem_add :需要写入的内存地址
** 输 入 unsigned con_dat :需要写入的数据
** 输出 : 无
**************************************************************************/
void WriteQT(uchar mem_add,uchar con_dat)
{
i2cstart();
NOP();
if(i2cwt(W_ADD)==SLAW)
{
i2cwt(mem_add);//写内存地址
i2cwt(con_dat);//写配置数据
}
//else syserr=ERR_SLAW;
i2cstop();
}
/*************************************************************************
** 函数名称: uchar Read_key(void); //读按键状态程序
** 功能描述: 读取地址0,1,键状态
** 输 入 无
** 输出 返回键值 (0xff为未找到按键)
**************************************************************************/
uchar Read_key(void)
{
uchar sta_buf[3];
uchar i,j,key_num;
//---------------读QT60160按键状态---------------------
i2cstart();//启动I2C
NOP();NOP();NOP();
if(i2cwt(W_ADD)==SLAW)//发送写器件地址
{
i2cwt(0x01);//发送要读取的QT内存地址
_NOP();
i2cstop(); //I2C停止
_NOP();
i2cstart(); //启动I2C
NOP();
i2cwt(R_ADD); //发送读器件地址
sta_buf[0]=i2crd();//读取QT内存0x01的值
sta_buf[1]=i2crd();//读取QT内存0x02的值
sta_buf[2]=i2crd();//读取QT内存0x02的值
_NOP();
i2cstop();
sta_buf[1]&=0b00011111;//屏蔽12以上的键
//---------------查找按下的键--------------------------
key_num=0;
for(i=0;i<2;i++)
{
if(sta_buf!=0x00)
{
for(j=0;j<8;j++)
{
if(sta_buf&0x01)
{
key_num=key_switch(key_num);
i2cstop();
return key_num;
}
key_num++;
sta_buf=sta_buf>>1;
}
}
else key_num+=0x08;
}
}
else i2cstop();
return 0xff;
}
/************************************************************************
** 函数名称: key_switch(key_num); //键值转换
** 功能描述: 按键盘布局转换成对应的值
** 输 入 key_num
** 输出 key_num
*************************************************************************/
uchar key_switch(uchar key_num)
{
uchar temp;
switch (key_num)
{
case 0:temp=1; break;
case 1:temp=4; break;
case 2:temp=7; break;
case 3:temp=10; break;
case 4:temp=3; break;
case 5:temp=6; break;
case 6:temp=9; break;
case 7:temp=11; break;
case 8:temp=2; break;
case 9:temp=5; break;
case 10:temp=8; break;
case 11:temp=0; break;
default:temp=0xff; break;
}
return temp;
}
最后面有个问题还要求助于各位大虾,由于我的应用比较特殊,因为是电池供电所以对功耗要求特别严。所以在待机的情况下MCU是睡觉的而且为了省电QT芯片也只留一个按键在工作,其它都关闭。当有人操作时必须象手机解锁一样,先按工作着的按键唤醒MCU,然后MCU再调用void switch_key(uchar contl)
打开所有通道的按键。操作完毕再次进入睡觉之前又要关闭所有的按键通道只留一个。
问题:现在逻缉功能上可以实现,让人受不了的是每次按下唤醒键打开所有通道后要等3秒左右所有按键才可以响引,就是说配置一次通道要3秒才可以使用。找过代理商的FAE,也是一问三不知。不知各位大虾有没这方面的经验? |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|