飞思卡尔kinetis学习资料之TSI模块
0赞
发表于 2/29/2012 10:36:55 PM
阅读(2832)
先来看点儿视频教程,老美真的很有才啊,放松一下
Kinetis K70 MCU: FPU 演示
(04:49 分钟) Kinetis 120MHz K10/20/60/70 MCUs 的浮点单位概述
Kinetis K50微控制器ARM Cortex M4医院手术室演示
(05:25分钟) 演示基于塔式 TWR-K53N512的Kinetis K50用于心电图和脉搏
(05:25分钟) 演示基于塔式 TWR-K53N512的Kinetis K50用于心电图和脉搏
TSI-触摸感应接口,是kinetis专门为电容触摸感应传感器而设计的接口模块,使用它可以轻松地实现用户输入控制。TSI包括两个部分:驱动电路和逻辑接口。驱动电路主要作用是驱动电容传感器,提供rc滤波等。而逻辑接口电路主要扫描多大16个感应传感器,测量、输出结果、产生中断等。
主要特性:
1、低功耗模式下检测
2、自动周期扫描和软件触发扫描
3、低功耗模式下电流小于1uA
4、最多16路输入,每个输入都有单独的结果寄存器
5、自动检测电容改变,门槛电压可调
6、TSI中断,每次扫描完成都可根据扫描结果产生中断
7、短路检测
下面是一个在飞思卡尔k60tower system上写的tsi应用程序,程序检测四个触摸按键的状态,并翻转四个一一对应的led灯。
#include "TSI.h"
extern uint32 __VECTOR_RAM[];
uint16 g16ElectrodeTouch[16] = {0};
uint16 g16ElectrodeBaseline[16] = {0};
uint16 g16ElectrodeBaseline[16] = {0};
uint32 g32DebounceCounter[16] = {DBOUNCE_COUNTS};
/********************************************************************************
* TSI_Init: Initializes TSI module
* Notes:
* -
********************************************************************************/
void TSI_Init(void)
{
SIM_SCGC5 |= (SIM_SCGC5_TSI_MASK); //Turn on clock to TSI module
* TSI_Init: Initializes TSI module
* Notes:
* -
********************************************************************************/
void TSI_Init(void)
{
SIM_SCGC5 |= (SIM_SCGC5_TSI_MASK); //Turn on clock to TSI module
#ifdef TWR_K60N512
PORTA_PCR4 = PORT_PCR_MUX(0); //Enable ALT0 for portA4
PORTB_PCR2 = PORT_PCR_MUX(0); //Enable ALT0 for portB2
PORTB_PCR3 = PORT_PCR_MUX(0); //Enable ALT0 for portB3
PORTB_PCR16 = PORT_PCR_MUX(0); //Enable ALT0 for portB16
PORTA_PCR4 = PORT_PCR_MUX(0); //Enable ALT0 for portA4
PORTB_PCR2 = PORT_PCR_MUX(0); //Enable ALT0 for portB2
PORTB_PCR3 = PORT_PCR_MUX(0); //Enable ALT0 for portB3
PORTB_PCR16 = PORT_PCR_MUX(0); //Enable ALT0 for portB16
#else
PORTB_PCR16 = PORT_PCR_MUX(0); //Enable ALT0 for portB16
PORTB_PCR17 = PORT_PCR_MUX(0); //Enable ALT0 for portB17
PORTB_PCR18 = PORT_PCR_MUX(0); //Enable ALT0 for portB18
PORTB_PCR19 = PORT_PCR_MUX(0); //Enable ALT0 for portB19
PORTB_PCR16 = PORT_PCR_MUX(0); //Enable ALT0 for portB16
PORTB_PCR17 = PORT_PCR_MUX(0); //Enable ALT0 for portB17
PORTB_PCR18 = PORT_PCR_MUX(0); //Enable ALT0 for portB18
PORTB_PCR19 = PORT_PCR_MUX(0); //Enable ALT0 for portB19
#endif
TSI0_GENCS |= ((TSI_GENCS_NSCN(10))|(TSI_GENCS_PS(3)));
TSI0_SCANC |= ((TSI_SCANC_EXTCHRG(3))|(TSI_SCANC_REFCHRG(31))|(TSI_SCANC_DELVOL(7))|(TSI_SCANC_SMOD(0))|(TSI_SCANC_AMPSC(0)));
TSI0_SCANC |= ((TSI_SCANC_EXTCHRG(3))|(TSI_SCANC_REFCHRG(31))|(TSI_SCANC_DELVOL(7))|(TSI_SCANC_SMOD(0))|(TSI_SCANC_AMPSC(0)));
ELECTRODE_ENABLE_REG = ELECTRODE0_EN_MASK|ELECTRODE1_EN_MASK|ELECTRODE2_EN_MASK|ELECTRODE3_EN_MASK;
TSI0_GENCS |= (TSI_GENCS_TSIEN_MASK); //Enables TSI
/* Init TSI interrupts */
enable_irq(83); //TSI Vector is 99. IRQ# is 99-16=83
/***********************/
enable_irq(83); //TSI Vector is 99. IRQ# is 99-16=83
/***********************/
}
/********************************************************************************
* TSI_SelfCalibration: Simple auto calibration version
* Notes:
* - Very simple, only sums a prefixed amount to the current baseline
********************************************************************************/
void TSI_SelfCalibration(void)
{
TSI0_GENCS |= TSI_GENCS_SWTS_MASK;
* TSI_SelfCalibration: Simple auto calibration version
* Notes:
* - Very simple, only sums a prefixed amount to the current baseline
********************************************************************************/
void TSI_SelfCalibration(void)
{
TSI0_GENCS |= TSI_GENCS_SWTS_MASK;
while(!TSI0_GENCS&TSI_GENCS_EOSF_MASK){};
delay(25000);
g16ElectrodeBaseline[ELECTRODE0] = ELECTRODE0_COUNT;
ELECTRODE0_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE0]+ELECTRODE0_OVRRUN));
g16ElectrodeTouch[ELECTRODE0] = g16ElectrodeBaseline[ELECTRODE0] + ELECTRODE0_TOUCH;
ELECTRODE0_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE0]+ELECTRODE0_OVRRUN));
g16ElectrodeTouch[ELECTRODE0] = g16ElectrodeBaseline[ELECTRODE0] + ELECTRODE0_TOUCH;
g16ElectrodeBaseline[ELECTRODE1] = ELECTRODE1_COUNT;
ELECTRODE1_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE1]+ELECTRODE1_OVRRUN));
g16ElectrodeTouch[ELECTRODE1] = g16ElectrodeBaseline[ELECTRODE1] + ELECTRODE1_TOUCH;
ELECTRODE1_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE1]+ELECTRODE1_OVRRUN));
g16ElectrodeTouch[ELECTRODE1] = g16ElectrodeBaseline[ELECTRODE1] + ELECTRODE1_TOUCH;
g16ElectrodeBaseline[ELECTRODE2] = ELECTRODE2_COUNT;
ELECTRODE2_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE2]+ELECTRODE2_OVRRUN));
g16ElectrodeTouch[ELECTRODE2] = g16ElectrodeBaseline[ELECTRODE2] + ELECTRODE2_TOUCH;
ELECTRODE2_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE2]+ELECTRODE2_OVRRUN));
g16ElectrodeTouch[ELECTRODE2] = g16ElectrodeBaseline[ELECTRODE2] + ELECTRODE2_TOUCH;
g16ElectrodeBaseline[ELECTRODE3] = ELECTRODE3_COUNT;
ELECTRODE3_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE3]+ELECTRODE3_OVRRUN));
g16ElectrodeTouch[ELECTRODE3] = g16ElectrodeBaseline[ELECTRODE3] + ELECTRODE3_TOUCH;
ELECTRODE3_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE3]+ELECTRODE3_OVRRUN));
g16ElectrodeTouch[ELECTRODE3] = g16ElectrodeBaseline[ELECTRODE3] + ELECTRODE3_TOUCH;
DISABLE_TSI;
}
/********************************************************************************
* TSI_isr: TSI interrupt subroutine
* Notes:
* -
********************************************************************************/
* TSI_isr: TSI interrupt subroutine
* Notes:
* -
********************************************************************************/
void TSI_isr(void)
{
static uint16 TouchEvent = 0;
uint16 lValidTouch = 0;
uint16 l16Counter;
{
static uint16 TouchEvent = 0;
uint16 lValidTouch = 0;
uint16 l16Counter;
TSI0_GENCS |= TSI_GENCS_OUTRGF_MASK;
TSI0_GENCS |= TSI_GENCS_EOSF_MASK;
TSI0_GENCS |= TSI_GENCS_EOSF_MASK;
/* Process electrode 0 */
l16Counter = ELECTRODE0_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE0]) //See if detected a touch
{
TouchEvent |= (1<<ELECTRODE0); //Set touch event variable
g32DebounceCounter[ELECTRODE0]--; //Decrement debounce counter
if(!g32DebounceCounter[ELECTRODE0]) //If debounce counter reaches 0....
{
lValidTouch |= ((1<<ELECTRODE0)); //Signal that a valid touch has been detected
TouchEvent &= ~(1<<ELECTRODE0); //Clear touch event variable
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE0); //Clear touch event variable
g32DebounceCounter[ELECTRODE0] = DBOUNCE_COUNTS; //Reset debounce counter
}
/***********************/
/* Process electrode 1 */
l16Counter = ELECTRODE1_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE1])
{
TouchEvent |= (1<<ELECTRODE1);
g32DebounceCounter[ELECTRODE1]--;
if(!g32DebounceCounter[ELECTRODE1])
{
lValidTouch |= ((1<<ELECTRODE1));
TouchEvent &= ~(1<<ELECTRODE1);
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE1);
g32DebounceCounter[ELECTRODE1] = DBOUNCE_COUNTS;
}
/***********************/
l16Counter = ELECTRODE1_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE1])
{
TouchEvent |= (1<<ELECTRODE1);
g32DebounceCounter[ELECTRODE1]--;
if(!g32DebounceCounter[ELECTRODE1])
{
lValidTouch |= ((1<<ELECTRODE1));
TouchEvent &= ~(1<<ELECTRODE1);
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE1);
g32DebounceCounter[ELECTRODE1] = DBOUNCE_COUNTS;
}
/***********************/
/* Process electrode 2 */
l16Counter = ELECTRODE2_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE2])
{
TouchEvent |= (1<<ELECTRODE2);
g32DebounceCounter[ELECTRODE2]--;
if(!g32DebounceCounter[ELECTRODE2])
{
lValidTouch |= ((1<<ELECTRODE2));
TouchEvent &= ~(1<<ELECTRODE2);
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE2);
g32DebounceCounter[ELECTRODE2] = DBOUNCE_COUNTS;
}
/***********************/
l16Counter = ELECTRODE2_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE2])
{
TouchEvent |= (1<<ELECTRODE2);
g32DebounceCounter[ELECTRODE2]--;
if(!g32DebounceCounter[ELECTRODE2])
{
lValidTouch |= ((1<<ELECTRODE2));
TouchEvent &= ~(1<<ELECTRODE2);
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE2);
g32DebounceCounter[ELECTRODE2] = DBOUNCE_COUNTS;
}
/***********************/
/* Process electrode 3 */
l16Counter = ELECTRODE3_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE3])
{
TouchEvent |= (1<<ELECTRODE3);
g32DebounceCounter[ELECTRODE3]--;
if(!g32DebounceCounter[ELECTRODE3])
{
lValidTouch |= ((1<<ELECTRODE3));
TouchEvent &= ~(1<<ELECTRODE3);
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE3);
g32DebounceCounter[ELECTRODE3] = DBOUNCE_COUNTS;
}
/***********************/
l16Counter = ELECTRODE3_COUNT;
if(l16Counter>g16ElectrodeTouch[ELECTRODE3])
{
TouchEvent |= (1<<ELECTRODE3);
g32DebounceCounter[ELECTRODE3]--;
if(!g32DebounceCounter[ELECTRODE3])
{
lValidTouch |= ((1<<ELECTRODE3));
TouchEvent &= ~(1<<ELECTRODE3);
}
}
else
{
TouchEvent &= ~(1<<ELECTRODE3);
g32DebounceCounter[ELECTRODE3] = DBOUNCE_COUNTS;
}
/***********************/
if(lValidTouch&((1<<ELECTRODE0))) //If detected a valid touch...
{
LED0_TOGGLE; //Toggle LED
lValidTouch &= ~((1<<ELECTRODE0)); //Clear valid touch
}
if(lValidTouch&((1<<ELECTRODE1)))
{
LED1_TOGGLE;
lValidTouch &= ~((1<<ELECTRODE1));
}
if(lValidTouch&((1<<ELECTRODE2)))
{
LED2_TOGGLE;
lValidTouch &= ~((1<<ELECTRODE2));
}
if(lValidTouch&((1<<ELECTRODE3)))
{
LED3_TOGGLE;
lValidTouch &= ~((1<<ELECTRODE3));
}
{
LED0_TOGGLE; //Toggle LED
lValidTouch &= ~((1<<ELECTRODE0)); //Clear valid touch
}
if(lValidTouch&((1<<ELECTRODE1)))
{
LED1_TOGGLE;
lValidTouch &= ~((1<<ELECTRODE1));
}
if(lValidTouch&((1<<ELECTRODE2)))
{
LED2_TOGGLE;
lValidTouch &= ~((1<<ELECTRODE2));
}
if(lValidTouch&((1<<ELECTRODE3)))
{
LED3_TOGGLE;
lValidTouch &= ~((1<<ELECTRODE3));
}
TSI0_STATUS = 0xFFFFFFFF;
}
}
#include "misc.h"
/********************************************************************************
* delay: delay
* Notes:
* -
********************************************************************************/
void delay(uint32 i)
{
for(i;i;i--) //delay
{
}
}
* delay: delay
* Notes:
* -
********************************************************************************/
void delay(uint32 i)
{
for(i;i;i--) //delay
{
}
}
/********************************************************************************
* GPIO_Init: Initializes GPIO controlling LED
* Notes:
* -
********************************************************************************/
void GPIO_Init(void)
{
ENABLE_GPIO_CLOCKS;
* GPIO_Init: Initializes GPIO controlling LED
* Notes:
* -
********************************************************************************/
void GPIO_Init(void)
{
ENABLE_GPIO_CLOCKS;
LED0_EN;
LED1_EN;
LED2_EN;
LED3_EN;
LED1_EN;
LED2_EN;
LED3_EN;
LEDs_On();
LED_Dir_Out();
}
LED_Dir_Out();
}
void LEDs_On(void)
{
#ifdef CPU_MK60N512VMD100
GPIOA_PDDR = (1<<10)|(1<<11)|(1<<28)|(1<<29);
#else
GPIOB_PDDR = (1<<11);
GPIOC_PDDR = ((1<<7)|(1<<8)|(1<<9));
#endif
}
{
#ifdef CPU_MK60N512VMD100
GPIOA_PDDR = (1<<10)|(1<<11)|(1<<28)|(1<<29);
#else
GPIOB_PDDR = (1<<11);
GPIOC_PDDR = ((1<<7)|(1<<8)|(1<<9));
#endif
}
void LED_Dir_Out(void)
{
#ifdef CPU_MK60N512VMD100
GPIOA_PDOR &= ~((1<<10)|(1<<11)|(1<<28)|(1<<29));
#else
GPIOB_PDOR &= ~(1<<11);
GPIOC_PDOR &= ~((1<<7)|(1<<8)|(1<<9));
#endif
}
{
#ifdef CPU_MK60N512VMD100
GPIOA_PDOR &= ~((1<<10)|(1<<11)|(1<<28)|(1<<29));
#else
GPIOB_PDOR &= ~(1<<11);
GPIOC_PDOR &= ~((1<<7)|(1<<8)|(1<<9));
#endif
}