garfield

飞思卡尔kinetis学习资料之TSI模块

0
阅读(2832)

先来看点儿视频教程,老美真的很有才啊,放松一下

 

Kinetis K70 MCU: FPU 演示
(04:49 分钟) Kinetis 120MHz K10/20/60/70 MCUs 的浮点单位概述

 
Kinetis K70 MCU: LCD 演示
(05:14 分钟) Kinetis K70 系列LCD控制模块包括基本PEG演示的概述
 
 
Kinetis K50微控制器ARM Cortex M4医院手术室演示
(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};
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
#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
#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
#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)));
  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
  /***********************/
}
/********************************************************************************
 *   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;
  g16ElectrodeBaseline[ELECTRODE1] = ELECTRODE1_COUNT;
  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;
  g16ElectrodeBaseline[ELECTRODE3] = ELECTRODE3_COUNT;
  ELECTRODE3_OVERRUN = (uint32)((g16ElectrodeBaseline[ELECTRODE3]+ELECTRODE3_OVRRUN));
  g16ElectrodeTouch[ELECTRODE3] = g16ElectrodeBaseline[ELECTRODE3] + ELECTRODE3_TOUCH;
  DISABLE_TSI;
}
/********************************************************************************
 *   TSI_isr: TSI interrupt subroutine
 * Notes:
 *    -
 ********************************************************************************/
void TSI_isr(void)
{
  static uint16 TouchEvent = 0;
  uint16 lValidTouch = 0;
  uint16 l16Counter;
  TSI0_GENCS |= TSI_GENCS_OUTRGF_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;
  }
  /***********************/
  /* 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;
  }
  /***********************/
  /* 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;
  }
  /***********************/
  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));
  }
  TSI0_STATUS = 0xFFFFFFFF;
}
 
#include "misc.h"
 
 
/********************************************************************************
 *   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;
  LED0_EN;
  LED1_EN;
  LED2_EN;
  LED3_EN;
  LEDs_On();
  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
}
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
}