⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f413 touchpad demo general.c

📁 TI公司MSP430单片机实现圆形和条形触摸按键的C语言源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:

//*****************************************************************************

#include <msp430x41x.h>
#include "lcd.h"

#define FALSE 0
#define TRUE (!FALSE)

// This structure defines the static data to maintain one key
typedef struct
{
    unsigned char port;
    unsigned char port_bit;
} key_config_data_t;

// This structure defines the working data to maintain one key
typedef struct
{
    int base_capacitance;     //this stores the base capacitance
    int filtered;             //this stores the filtered result with gain
    int adapt;                //this stores the slow adaptation counter
    int adapt_flag;           //this is for debug purpose only
//    long filtered;
} key_data_t;


#define SQUARE               0


#define RECTANGLE              0

#define OUTPUT_I2C              0     //tells the board to wait for I2C master
                                      //make sure you have the right hardware
                                      //connected when you enable this option!!

#define LOW_POWER               1

#if SQUARE
// This definition allows the number of keys to be set
#define NUM_KEYS    	        12
#define NUM_SCROLL_KEYS         12

#else

#define NUM_KEYS    	        16
#define NUM_SCROLL_KEYS         16

#endif



unsigned char tx_bit;   
unsigned char reg_tx;   

/* This is defined to enable support for power saving mode, on command from the
   host. It is made a definition, as it is convenient to disable this function
   during testing. */
//#define SUPPORT_POWER_DOWN

const key_config_data_t key_config[NUM_KEYS] =
{
#if SQUARE
    /* Strip */
    {1,BIT1},                                                           //端口1,位1        
    {1,BIT3},                                                           //端口1,位3        
    {1,BIT5},                                                           //端口1,位5        
    {1,BIT7},                                                           //端口1,位7        
    {2,BIT0},                                                           //端口2,位0        
    {2,BIT1},                                                           //端口2,位1        
    {2,BIT3},                                                           //端口2,位3        
    {2,BIT2},                                                           //端口2,位2        
    {2,BIT5},                                                           //端口2,位5        
    {2,BIT4},                                                           //端口2,位4        
    {2,BIT7},                                                           //端口2,位7        
    {2,BIT6},                                                           //端口2,位6        
#elif RECTANGLE
  {1,BIT4},//{1,BIT5},
  {1,BIT6},//{1,BIT4},
  {2,BIT0},//{1,BIT3},
  {2,BIT2},//{1,BIT2},
  {1,BIT2},//{1,BIT6},
  {1,BIT0},//{1,BIT7},
  {1,BIT5},//{2,BIT2},
  {1,BIT7},//{2,BIT3},  
  {2,BIT3},//{2,BIT5},
  {2,BIT1},//{2,BIT4},
  {2,BIT4},//{1,BIT1},
  {2,BIT6},//{1,BIT0},
  {1,BIT1},//{2,BIT0},
  {1,BIT3},//{2,BIT1},
  {2,BIT5},//{2,BIT6},
  {2,BIT7},//{2,BIT7},  
    
#else 
    {2,BIT7},// {1, BIT3},               
    {2,BIT5},// {1, BIT2},               
    {2,BIT3},// {1, BIT1},               
    {2,BIT1},// {1, BIT0},               
    {1,BIT7},// {2, BIT7},               
    {1,BIT5},// {2, BIT6},               
    {1,BIT3},// {2, BIT5},               
    {1,BIT1},// {2, BIT4},               
    {1,BIT0},// {2, BIT3},               
    {1,BIT2},// {2, BIT2},               
    {1,BIT4},// {2, BIT1},               
    {1,BIT6},// {2, BIT0},               
    {2,BIT0},// {1, BIT7},               
    {2,BIT2},// {1, BIT6},               
    {2,BIT4},// {1, BIT5},               
    {2,BIT6},// {1, BIT4},              

#endif    
};


unsigned int timer_count;

long key_threshold;       //A master threshold value determines the
                                  //sensitivity of the whole keyboard

int cap_fudge = 0;

volatile int usci_hit = FALSE;

unsigned char key_queue[8];
volatile int key_in;
volatile int key_out;

 unsigned char stuff[20];
int stuffp = 0;
int stuffpx = 0;
int stuffpy = 0;

int low_power_counter;

key_data_t key[NUM_KEYS];

void i2c_config(void);


//================================================================
//函数名称:void Uart_Tx(int reg_key_value)                       
//型参类型:空                                                    
//返回类型:空                                                    
//函数功能:把当前键值通过模拟串口送给上位机(19200,n,8,1)         
//================================================================
//int tmp_reg_key_value;                                            
void Uart_Tx(int reg_key_value)                                   
{                                                                 
  if(reg_key_value == -1)                                         
  {                                                               
    _NOP();                                                       
  }                                                               
  else                                                            
  {                                                               
 
        P6DIR |= 0x01;                            // P6.0 output  
        CCTL0 = CCIE;                             // CCR0 interrupt en
        CCR0 = 209;                                                   
        TACTL = TASSEL_2 + MC_1;                  // SMCLK, continuous
        P6OUT =0x01;                                                  
        reg_tx=reg_key_value%256;                                     
       _BIS_SR(LPM0_bits + GIE);                                     
       CCTL0 &= ~CCIE;                                               
       TACTL = TASSEL_2 + MC_2;                                      
                      
  }                                                               
}                                                                 

void init_key(key_data_t *key, const key_config_data_t *key_config)
{
    key->base_capacitance = 0;
    key->filtered = 0;
    key->adapt = 0;

    /* Set the capacitive sense pin to output, low level, low going interupts */
    /* We need to keep all switches, except the one we are currently sensing,
       driven low so they form the "ground" against which the active pad and the
       finger form the variable capacitance. The end pads in the row can be
       expected to give a weaker response, because they are not surrounded by
       grounded keys on both sides, as the other keys are. */
    if (key_config->port == 1)
    {
        P1OUT &= ~key_config->port_bit;
        P1DIR |= key_config->port_bit;
        P1IES |= key_config->port_bit;
    }
    else
    {
        P2OUT &= ~key_config->port_bit;
        P2DIR |= key_config->port_bit;
        P2IES |= key_config->port_bit;
    }
}

int xkey;

unsigned int measure_key_capacitance(int key_no)
{
    char active_key;
    const key_config_data_t *keyp;
    const key_config_data_t *partner;
    int sum;
   unsigned int i;

    xkey = key_no;
    keyp = &key_config[key_no];
    partner = &key_config[key_no ^ 1];
    do
    {
        /* Right now, all keys should be driven low, forming a "ground" area */
        active_key = keyp->port_bit;
        usci_hit = FALSE;
        /* Take the active key high to charge the pad */
        if (keyp->port == 1)
            P1OUT |= active_key;
        else
            P2OUT |= active_key;
        /* Allow a short time for the hard pull high to really charge the pad */
        _NOP();
        _NOP();
        _NOP();
        
        for(i=0;i<200;i++); 
          WDTCTL = WDTPW + WDTHOLD;            
            IE1 &= ~WDTIE;

        if (keyp->port == 1)
        {
            P1IES |= active_key;
            P1IE |= active_key;
            P1DIR &= ~active_key;
        }
        else
        {
            P2IES |= active_key;
            P2IE |= active_key;
            P2DIR &= ~active_key;
        }
        
           WDTCTL = WDT_ADLY_1000;                     // Set Watchdog Timer interval to ~30ms
           IE1 |= WDTIE;                             // Enable WDT interrupt
                                                      // enable WDT which deals with low power scan
      
     
       
        /* Take a snaphot of the timer... */
        timer_count = TAR;
        /* ...and wait for the discharge to cause an interrupt. We wait in LPM0 mode, as we
           need the fast clock running to perform accurate timing of the discharge. We
           need to minimise noise disturbing the discharge time. We should, therefore, have
           all unnecessary peripherals idle. We do not want other interrupts spoiling the
           crispness of our reponse to the port interrupt, so all other interrupts should
           be turned off at this time. */
        LPM0;
        /* Return the key to the driven low state, to contribute to the "ground" area
           around the next key to be scanned. */
        
          
        
        if (keyp->port == 1)
        {
	    P1IE &= ~active_key;            // disable active key interrupt
            P1OUT &= ~active_key;           // switch active key to low to discharge the key
    	    P1DIR |= active_key;            // switch active key to output low to save power
        }
        else
        {
	    P2IE &= ~active_key;            // disable active key interrupt
    	    P2OUT &= ~active_key;           // switch active key to low to discharge the key
    	    P2DIR |= active_key;            // switch active key to output low to save power
        }
    }
    while (usci_hit);
    sum = timer_count;
    do
    {
        /* Right now, all keys should be driven low, forming a "ground" area */
        active_key = keyp->port_bit;
        usci_hit = FALSE;
        /* Take the partner key high to charge the pad */
        if (partner->port == 1)
            P1OUT |= partner->port_bit;
        else
            P2OUT |= partner->port_bit;
        /* Allow a short time for the hard pull high to really charge the pad */
        _NOP();
        _NOP();
        _NOP();
         for(i=0;i<200;i++); 
        // Enable interrupts (edge is already set to low going trigger)
        // set the active key to input (was output high), and start the
        // timed discharge of the pad.
          WDTCTL = WDT_ADLY_1000;                     // Set Watchdog Timer interval to ~30ms
           IE1 |= WDTIE;   
        if (keyp->port == 1)
        {
            P1IES &= ~active_key;
            P1IE |= active_key;
            P1DIR &= ~active_key;
        }
        else
        {
            P2IES &= ~active_key;
            P2IE |= active_key;
            P2DIR &= ~active_key;
        }
        
                                   // Enable WDT interrupt
                                                      // enable WDT which deals with low power scan
        /* Take a snaphot of the timer... */
        timer_count = TAR;
        /* ...and wait for the discharge to cause an interrupt. We wait in LPM0 mode, as we
           need the fast clock running to perform accurate timing of the discharge. We
           need to minimise noise disturbing the discharge time. We should, therefore, have
           all unnecessary peripherals idle. We do not want other interrupts spoiling the
           crispness of our reponse to the port interrupt, so all other interrupts should
           be turned off at this time. */
        LPM0;
        /* Return the key to the driven low state, to contribute to the "ground" area
           around the next key to be scanned. */
        
         WDTCTL = WDTPW + WDTHOLD;            
            IE1 &= ~WDTIE;
        if (keyp->port == 1)
        {
	    P1IE &= ~active_key;            // disable active key interrupt
            P1OUT &= ~active_key;           // switch active key to low to discharge the key
    	    P1DIR |= active_key;            // switch active key to output low to save power
        }
        else
        {
	    P2IE &= ~active_key;            // disable active key interrupt
    	    P2OUT &= ~active_key;           // switch active key to low to discharge the key
    	    P2DIR |= active_key;            // switch active key to output low to save power
        }
        if (partner->port == 1)
            P1OUT &= ~partner->port_bit;
        else
            P2OUT &= ~partner->port_bit;
    }
    while (usci_hit);
    sum += timer_count;
    return sum >> 1;
}

int snapshot = 0;
int stepper = 0;

int scan_keys(void)
{
    int i;
    int margin;

    for (i = 0;  i < NUM_KEYS;  i++)
    {
        stepper = i;
        margin = measure_key_capacitance(i) - key[i].base_capacitance;
        key[i].filtered += (margin - (key[i].filtered >> 4));
    }
    return 0;
}



    
int find_mean_position(void)
{
    long a;
    long b;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -