打印

【TI 技术资料分享】+lantchpad的电容式触摸板的源码

[复制链接]
1040|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
必胜客A|  楼主 | 2015-3-9 21:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 必胜客A 于 2015-3-9 21:52 编辑

TI公司MSP430芯片评估板lantchpad的电容式触摸板的源码 TI公司MSP430芯片评估板lantchpad的电容式触摸板的源码.zip (9.96 KB)

#include "CTS_Layer.h"
#include "uart.h"


#define WAKE_UP_UART_CODE       0xBE
#define WAKE_UP_UART_CODE2      0xEF
#define SLEEP_MODE_UART_CODE    0xDE
#define SLEEP_MODE_UART_CODE2   0xAD
#define MIDDLE_BUTTON_CODE      0x80
#define INVALID_GESTURE         0xFD
#define GESTURE_START           0xFC
#define GESTURE_STOP            0xFB
#define COUNTER_CLOCKWISE       1
#define CLOCKWISE               2
#define GESTURE_POSITION_OFFSET 0x20
#define WHEEL_POSITION_OFFSET   0x30

#define WHEEL_TOUCH_DELAY       12  //Delay between re-sendings of touches
#define MAX_IDLE_TIME           200
#define PROXIMITY_THRESHOLD     60

unsigned int wheel_position=ILLEGAL_SLIDER_WHEEL_POSITION, last_wheel_position=ILLEGAL_SLIDER_WHEEL_POSITION;
unsigned int deltaCnts[1];
unsigned int prox_raw_Cnts;




/*----------------- LED definition---------------------------------------------
* There are 8 LEDs to represent different positions around the wheel. They are
* controlled by 5 pins of Port 1 using a muxing scheme. The LEDs are divided
* vertically into two groups of 4, in which each LED is paired up [muxed] with
* the LED mirrored on the other side of the imaginary center vertical line via
* the use of pin P1.3 and one specific port pin.
* Specifically, the pairs are LEDs [0,7], [1,6], [2,5], [3,4], as shown in the
* diagram below.
*     LED                        Position (degrees, clockwise)
* --RIGHT SIDE--
*      0       BIT4,!BIT3                  45
*      1       BIT5,!BIT3                  80
*      2       BIT6,!BIT3                 100
*      3       BIT7,!BIT3                 135 *
*
* --LEFT SIDE--
*      4       BIT3,(BIT4,5,6)             225
*      5       BIT3,(BIT4,5,7)             260
*      6       BIT3,(BIT4,6,7)             280
*      7       BIT3,(BIT5,6,7)             315
*----------------------------------------------------------------------------*/
#define MASK7                   BIT4
#define MASK6                   BIT5
#define MASK5                   BIT6
#define MASK4                   BIT7

#define MASK3                   (BIT3+BIT4+BIT5+BIT6)
#define MASK2                   (BIT3+BIT4+BIT5+BIT7)
#define MASK1                   (BIT3+BIT4+BIT6+BIT7)
#define MASK0                   (BIT3+BIT5+BIT6+BIT7)

const unsigned char LedWheelPosition[16] =
                                {
                                  MASK0, MASK0, MASK0 & MASK1, MASK1,
                                  MASK1 & MASK2, MASK2, MASK2 & MASK3, MASK3,
                                  MASK4, MASK4, MASK4 | MASK5, MASK5,
                                  MASK5 | MASK6,  MASK6, MASK6 | MASK7, MASK7
                                };
const unsigned char startSequence[8] =
                                {
                                  MASK0,
                                  MASK1,
                                  MASK2,
                                  MASK3,
                                  MASK4,
                                  MASK5,
                                  MASK6,
                                  MASK7
                                };
/*----------------- LED definition------------------------------*/


void InitLaunchPadCore(void)

{
  BCSCTL1 |= DIVA_0;                    // ACLK/(0:1,1:2,2:4,3:8)
  BCSCTL3 |= LFXT1S_2;                  // LFXT1 = VLO  
  
  // Port init
  P1OUT &= ~(BIT3+BIT4+BIT5+BIT6+BIT7+BIT0);
  P1DIR |= BIT3+BIT4+BIT5+BIT6+BIT7+BIT0;
  P2SEL = 0x00;                         // No XTAL
  P2DIR |= (BIT0+BIT4+BIT2+BIT3+BIT1+BIT5);
  P2OUT &= ~(BIT0+BIT4+BIT2+BIT3+BIT1+BIT5);
}

void SendByte(unsigned char touch)
{
  TimerA_UART_init();
  TimerA_UART_tx(touch);
  TimerA_UART_shutdown();  
}

/* ----------------CapTouchIdleMode-----------------------------------------
* Device stays in LPM3 'sleep' mode, only Proximity Sensor is used to detect
* any movement triggering device wake up                                 
* ------------------------------------------------------------------------*/
void CapTouchIdleMode(void)
{
  /* Send status via UART: 'sleep' = [0xDE, 0xAD] */  
  SendByte(SLEEP_MODE_UART_CODE);
  SendByte(SLEEP_MODE_UART_CODE2);
  
  /* Set DCO to 1MHz */
  /* Set SMCLK to 1MHz / 8 = 125kHz */
  BCSCTL1 = CALBC1_1MHZ;               
  DCOCTL = CALDCO_1MHZ;
  BCSCTL2 |= DIVS_3;  
  
  P1OUT |= BIT0;                            // Turn on center LED   
  deltaCnts[0] = 0;
  
  /* Sleeping in LPM3 with ACLK/100 = 12Khz/100 = 120Hz wake up interval */
  /* Measure proximity sensor count upon wake up */
  /* Wake up if proximity deltaCnts > THRESHOLD */  
  do
  {
    TACCR0 = 100;                                                                                                                                               
    TACTL = TASSEL_1 + MC_1;                  
    TACCTL0 |= CCIE;   
    __bis_SR_register(LPM3_bits+GIE);
    TACCTL0 &= ~CCIE;                             
    TI_CAPT_Custom(&proximity_sensor,deltaCnts);
  }
  while (deltaCnts[0] <= PROXIMITY_THRESHOLD);
  
  P1OUT &= ~BIT0;                           // Turn off center LED
}

/* ----------------MeasureCapBaseLine--------------------------------------
* Re-measure the baseline capacitance of the wheel elements & the center  
* button. To be called after each wake up event.                          
* ------------------------------------------------------------------------*/
void MeasureCapBaseLine(void)
{
  P1OUT = BIT0;
  /* Set DCO to 8MHz */
  /* SMCLK = 8MHz/8 = 1MHz */
  BCSCTL1 = CALBC1_8MHZ;     
  DCOCTL = CALDCO_8MHZ;
  BCSCTL2 |= DIVS_3;
  
  TI_CAPT_Init_Baseline(&wheel);
  TI_CAPT_Update_Baseline(&wheel,2);
  TI_CAPT_Init_Baseline(&middle_button);
  TI_CAPT_Update_Baseline(&middle_button,2);  
}

/* ----------------LedStartUpSequence--------------------------------------
* Display an LED lighting sequence to indicate the wake up event
* ------------------------------------------------------------------------*/
void LedStartUpSequence(void)
{
  unsigned char i;
  TACCTL0 = CCIE;                           // CCR0 interrupt enabled
  TACTL |= TACLR;
  TACCR0 = TAR + 500;                       // 50ms                             
  TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
  
  /* Slow clockwise sequence */
  for(i=0; i<8; i++)
  {
      P1OUT = startSequence[i];
      __bis_SR_register(LPM3_bits+GIE);
     
      __delay_cycles(1000000);
      TACCR0 = TAR + 500;   // 50ms                             
  }

  P1OUT = BIT0;
  /* Fast counter-clockwise sequence */
  while(i)
  {
      i--;
      P1OUT = startSequence[i];
      __bis_SR_register(LPM3_bits+GIE);
      TACCR0 = TAR + 500;   // 50ms                             
  }
  TACCTL0 &= ~CCIE;                         // CCR0 interrupt disabled
  P1OUT = 0;                                // Turn off all LEDs
}

/* ----------------GetGesture----------------------------------------------
* Determine immediate gesture based on current & previous wheel position
* ------------------------------------------------------------------------*/
unsigned char GetGesture(unsigned char wheel_position)
{
unsigned char gesture = INVALID_GESTURE, direction, ccw_check, cw_check;
// ******************************************************************************
// gesturing
// determine if a direction/swipe is occuring
// the difference between the initial position and
// the current wheel position should not exceed 8
// 0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F-0...
//
// E-F-0-1-2:  cw, 4
// 2-1-0-F-E: ccw, 4
// A-B-C-D-E-F

  //if(initial_wheel_position == INVALID_WHEEL_POSITION)
  //{
    //gesture = 0;
    //initial_wheel_position = wheel_position;
  //}
  //else

  if(last_wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
  {
    if(last_wheel_position  > wheel_position)
    {
      // E-D-C-B-A:  ccw, 4
      // counter clockwise: 0 < (init_wheel_position - wheel_position) < 8
      //                    gesture = init_wheel_position - wheel_position
      //
      // E-F-0-1-2:  cw, 4
      // clockwise:        0 < (init_wheel_position+wheel_position)-16 <8
      //                    
      ccw_check = last_wheel_position  - wheel_position;
      if(ccw_check < 8)
      {
        gesture = ccw_check;
        direction = COUNTER_CLOCKWISE;
      }
      else
      {
        // E-F-0-1-2:  cw, 4
        // 16 - 14 + 2 = 4
        cw_check = 16 - last_wheel_position  + wheel_position ;
        if(cw_check < 8)
        {
            gesture = cw_check;
            direction = CLOCKWISE;
        }
      }
    }
    else
    {
      // initial_wheel_position <= wheel_position
      //
      // 2-1-0-F-E: ccw, 4
      // counter clockwise:
      //                    0 < (init_wheel_position+wheel_position)-16 <8
      //                    gesture = init_wheel_position - wheel_position
      //
      // 0-1-2-3-4:  cw, 4
      // clockwise:        0 < (wheel_position - init_wheel_position) < 8
      //   
      cw_check = wheel_position - last_wheel_position ;
      if(cw_check < 8)
      {
        gesture = cw_check;
        direction = CLOCKWISE;
      }
      else
      {
        // 2-1-0-F-E: ccw, 4
        // 16 + 2 - 14 = 4
        ccw_check = 16 + last_wheel_position  - wheel_position ;
        if(ccw_check < 8)
        {
          gesture = ccw_check;
          direction = COUNTER_CLOCKWISE;
        }
      }
    }
  }
  if (gesture == INVALID_GESTURE)
          return gesture;
  if (direction == COUNTER_CLOCKWISE)
    return (gesture + 16);
  else
    return gesture;
}

/* ----------------CapTouchActiveMode----------------------------------------------
* Determine immediate gesture based on current & previous wheel position
*
*
*
*
*
*
*
* -------------------------------------------------------------------------------*/
void CapTouchActiveMode()
{
  unsigned char idleCounter, activeCounter;
  unsigned char gesture, gestureDetected;
  unsigned char centerButtonTouched = 0;
  unsigned int wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;
  
     
  gesture = INVALID_GESTURE;            // Wipes out gesture history
  
  /* Send status via UART: 'wake up' = [0xBE, 0xEF] */  
  SendByte(WAKE_UP_UART_CODE);
  SendByte(WAKE_UP_UART_CODE2);

  idleCounter = 0;      
  activeCounter = 0;
  gestureDetected = 0;
  
  while (idleCounter++ < MAX_IDLE_TIME)
  {  
          /* Set DCO to 8MHz */
          /* SMCLK = 8MHz/8 = 1MHz */
    BCSCTL1 = CALBC1_8MHZ;     
    DCOCTL = CALDCO_8MHZ;
    BCSCTL2 |= DIVS_3;  
    TACCTL0 &= ~CCIE;   
   
    wheel_position = ILLEGAL_SLIDER_WHEEL_POSITION;      
    wheel_position = TI_CAPT_Wheel(&wheel);
   
    /* Process wheel touch/position/gesture  if a wheel touch is registered*/
    /* Wheel processing has higher priority than center button*/
   
    if(wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
    {
      centerButtonTouched = 0;
      
      /* Adjust wheel position based: rotate CCW by 2 positions */
      if (wheel_position < 0x08)
      {
         wheel_position += 0x40 - 0x08;
      }
      else
      {
         wheel_position -= 0x08;
            /* Adjust wheel position based: rotate CCW by 2 positions */
      }
      
      wheel_position = wheel_position >>2;  // divide by four
               
      gesture = GetGesture(wheel_position);            
      
      /* Add hysteresis to reduce toggling between wheel positions if no gesture
       * has been TRULY detected. */  
                  
      if ( (gestureDetected==0) && ((gesture<=1) || (gesture==0x11) || (gesture==0x10)))
      {
        if (last_wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
            wheel_position = last_wheel_position;
        gesture = 0;
      }
      
      /* Turn on corresponding LED(s) */
      P1OUT = (P1OUT & BIT0) | LedWheelPosition[wheel_position];
      
     
      if ((gesture != 0) && (gesture != 16) && (gesture != INVALID_GESTURE))           
      { /* A gesture has been detected */
        
        if (gestureDetected ==0)
        { /* Starting of a new gesture sequence */
          gestureDetected = 1;
         
          /* Transmit gesture start status update & position via UART to PC */
          SendByte(GESTURE_START);
          SendByte(last_wheel_position + GESTURE_POSITION_OFFSET);
        }
                 
        /* Transmit gesture & position via UART to PC */
        SendByte(gesture);
        SendByte(wheel_position + GESTURE_POSITION_OFFSET);
      }      
      else
        if (gestureDetected==0)
        { /* If no gesture was detected, this is constituted as a touch/tap */
          if (++wheelTouchCounter >= WHEEL_TOUCH_DELAY)
          {
                  /* Transmit wheel position [twice] via UART to PC */
                  wheelTouchCounter = 0;
                  SendByte(wheel_position + WHEEL_POSITION_OFFSET );
                  SendByte(wheel_position + WHEEL_POSITION_OFFSET );
          }
        }
               else
          wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;             
        
      idleCounter = 0;                      // Reset idle counter
      activeCounter++;
      last_wheel_position = wheel_position;
    }
    else   
    { /* no wheel position was detected */
      
      if(TI_CAPT_Button(&middle_button))
      { /* Middle button was touched */   
        if (centerButtonTouched==0)
        {
          /* Transmit center button code [twice] via UART to PC */
          SendByte(MIDDLE_BUTTON_CODE);         
          SendByte(MIDDLE_BUTTON_CODE);
                    
          centerButtonTouched = 1;
         
          P1OUT = (P1OUT&BIT0) ^ BIT0;      // Toggle Center LED
        }
        idleCounter = 0;
      }
      else   
      { /* No touch was registered at all [Not wheel or center button */
        centerButtonTouched = 0;
        P1OUT &= BIT0;      
        if ( (gesture == INVALID_GESTURE) || (gestureDetected ==0))
        { /* No gesture was registered previously */
          if (last_wheel_position  != ILLEGAL_SLIDER_WHEEL_POSITION)
            {
              /* Transmit last wheel position [twice] via UART to PC */
              SendByte(last_wheel_position  + WHEEL_POSITION_OFFSET );
              SendByte(last_wheel_position  + WHEEL_POSITION_OFFSET );
              wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;
            }
        }
         
          if (gestureDetected == 1)
          { /* A gesture was registered previously */
            
            /* Transmit status update: stop gesture tracking [twice] via UART to PC */
            SendByte(GESTURE_STOP);
            SendByte(GESTURE_STOP);
          }
         
      }
      
      // Reset all touch conditions, turn off LEDs,
      last_wheel_position= ILLEGAL_SLIDER_WHEEL_POSITION;      
      gesture = INVALID_GESTURE;
      gestureDetected = 0;

    }
   
  /* ------------------------------------------------------------------------
   * Option:
   * Add delay/sleep cycle here to reduce active duty cycle. This lowers power
   * consumption but sacrifices wheel responsiveness. Additional timing
   * refinement must be taken into consideration when interfacing with PC
   * applications GUI to retain proper communication protocol.
   * -----------------------------------------------------------------------*/
     
  }
}


void main(void)
{   

  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  
  InitLaunchPadCore();
   
  
  /* Set DCO to 1MHz */
  /* Set SMCLK to 1MHz / 8 = 125kHz */
  BCSCTL1 = CALBC1_1MHZ;               
  DCOCTL = CALDCO_1MHZ;
  BCSCTL2 |= DIVS_3;
  /* Establish baseline for the proximity sensor */  
  TI_CAPT_Init_Baseline(&proximity_sensor);
  TI_CAPT_Update_Baseline(&proximity_sensor,5);
  
  while (1)
  {
    CapTouchIdleMode();  
  
    MeasureCapBaseLine();
    LedStartUpSequence();
    CapTouchActiveMode();
  }
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

176

帖子

2

粉丝