花了一天时间写TSI按键代码,其实写代码只用了30分钟,但是看数据手册却用了我整整半天。擦!
不过一看TSI模块的寄存器只有3个,其实就可以知道这个模块并没有多复杂,复杂的地方在于机制的理解和参数的理解,数据手册有20页,也不算多。
该模块通过两个恒流源给按键充电时的时间差来确定按键是否按下,其中一个是参考恒流源。当按键按下的时候,按键的电容增大,用恒流源将其充满电所需的时间就会变长,这样就可以区分按键是否按下。当然这只是简单的解释。实际的检测过程比较复杂,也就是这个比较难以理解。
不得不说,数据手册的表达还是很到位的,区区20页,讲清楚了所有的操作机理,表达能力不可谓不强,几乎没有任何重复的叙述,所以每一句都很关键,都要细看。
之前听飞思卡尔的研讨会的时候,感觉飞思卡尔很明显对于自己的TSI设计很得意,重点提到多次。该模块确实设计的很了得,各种参数居然都可以设置,比如恒流源电流大小,重复检测多少次,参考电流源电流大小,充电充满与放电放空的电压差,里面还有分频器。不过说回来,正是因为东西这么多,才这么烦人。对于一个仅仅只做按键功能的东西,你整这么多寄存器,不觉得很麻烦吗?
下面是写的初始化代码:
void TSI_Init (void)
{
SIM_SCGC5 |= SIM_SCGC5_TSI_MASK; // Enable clock gating for TSI
/* Enable proper GPIO as TSI channels *///以下引脚的功能设置为TSI通道
PORTB_PCR18 = PORT_PCR_MUX(0); // PTB18 as TSI channel 11
PORTB_PCR19 = PORT_PCR_MUX(0); // PTB19 as TSI channel 12
PORTC_PCR0 =PORT_PCR_MUX(0); //channel 13
PORTC_PCR2 =PORT_PCR_MUX(0); //channel 15
PORTA_PCR1 =PORT_PCR_MUX(0); //channel 2
PORTA_PCR2 =PORT_PCR_MUX(0); //channel 3
PORTA_PCR4 =PORT_PCR_MUX(0); //channel 5
PORTB_PCR3 =PORT_PCR_MUX(0); //channel 8
enable_irq(TSI_irq_no);
TSI0_GENCS |= (TSI_GENCS_ESOR_MASK //End-of-scan interrupt is allowed
| TSI_GENCS_MODE(0) //Set TSI in capacitive sensing(non-noise detection) mode
| TSI_GENCS_REFCHRG(4) //8uA
| TSI_GENCS_DVOLT(0) //DV = 1.03 V; VP= 1.33 V; Vm= 0.30 V
| TSI_GENCS_EXTCHRG(7) //64uA
| TSI_GENCS_PS(4) //预分频16
| TSI_GENCS_NSCN(11) //扫描12次
// | TSI_GENCS_TSIIEN_MASK //中断允许
| TSI_GENCS_STPE_MASK //所有低功耗模式下照样运行
//| TSI_GENCS_STM_MASK //Trigger for the module 0=Sofware
);
TSI0_GENCS |= TSI_GENCS_TSIEN_MASK; //使能TSI模块
}
在测试中没有使用TSI中断,因为我还没摸清KL25的中断机理。我使用了查询办法,下面是代码:
int main (void)
{
unsigned int key2;
TSI_Init ();
TSI0_DATA |=TSI_DATA_TSICH(8); //打开第8通道
while (1)
{
TSI0_DATA |=TSI_DATA_SWTS_MASK; //软件使能 ,每次扫描完都要重新使能
while( TSI0_GENCS & TSI_GENCS_EOSF_MASK) //扫描完
{
key2 = TSI0_DATA &0xFFFF;
TSI0_GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
}
}
}
下面是调试截图,调试的是第8通道:
手没有按下按键时,恒流源给按键检测需要0x011A个tips;
手按下按键时,恒流源给按键检测需要0x041F个tips。如果我们设定一个阈值为0x0300就可以检测按键是否按下。