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

📄 fg439_magic_keys.c

📁 TI MSP430针对cap sense 按键的源码, 可实现单击或滑动键, 如IPOD上的人机接口.
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
    	IE2 |= BTIE;                   	    // Start basic timer interrupt (other timers could be used)
    	KEY_CHARGE_OUT |= KEY_CHARGE_BIT;   // Set key charging pin to high
    	KEY_CHARGE_DIR |= KEY_CHARGE_BIT;   // Set key charging pin to output
    	if (key_config->port == 1)
    	{
            P1OUT |= active_key;            // Switch active key to high to help charging
           	                            // Wait for 16mS to charge
    	}
    	else
    	{
    	    P2OUT |= active_key;
    	}
      	LPM0;

    	KEY_CHARGE_DIR &= ~KEY_CHARGE_BIT;  // Key charging pin = HiZ, charge complete
    	KEY_CHARGE_OUT &= ~KEY_CHARGE_BIT;  // Key charging pin = cleared, ready for discharge

        // interrupt enabled (edge is already lo trigger)
    	if (key_config->port == 1)
    	{
            P1DIR &= ~active_key;           // set the active key to input (was output high)
            P1IE |= active_key;
    	}
    	else
	{
            P2DIR &= ~active_key;           // set the active key to input (was output high)
            P2IE |= active_key;
	}
        timer_count = TAR;                  // Read TAR discharge
    	KEY_CHARGE_DIR |= KEY_CHARGE_BIT;   // Start discharge
    	LPM0;                               // Wait for P1 interrupt

    	if (key_config->port == 1)
    	{
	    P1IE &= ~active_key;            // disable active key interrupt
            P1OUT &= ~active_key;           // switch active key to low to help charging
    	    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 help charging
    	    P2DIR |= active_key;            // switch active key to output low to save power
    	}
    	KEY_CHARGE_OUT |= KEY_CHARGE_BIT;   // Ref Set
    	KEY_CHARGE_DIR |= KEY_CHARGE_BIT;   // Ref output
    	y += timer_count;                   // Accumulate timer_count
    }

    // The average of the 4 samples is taken
    return (y >> 2);
}

void init_key(key_data_t *key, const key_config_data_t *key_config)
{
    int i;

    key->acc_ref_time = 0;
    key->acc_ref_time_counter = 0;
    key->base_capacitance = 0;

    if (key_config->port == 1)
    {
        P1DIR |= key_config->port_bit;
        P1OUT |= key_config->port_bit;
        P1IES |= key_config->port_bit;    // Swtich the capacitive sense pin to low active
    }
    else
    {
        P2DIR |= key_config->port_bit;
        P2OUT |= key_config->port_bit;
        P2IES |= key_config->port_bit;    // Swtich the capacitive sense pin to low active
    }
    /* Calibrate the key */
    for (i = 0;  i < 18;  i++)
        key->base_capacitance = measure_key_capacitance(key_config);
}

int test_key(key_data_t *key, const key_config_data_t *key_config)
{
    int i;
    unsigned int ref_time;

    ref_time = measure_key_capacitance(key_config);
    if (ref_time > key->base_capacitance + 30)
    {
        key->acc_ref_time = 0;
      	key->acc_ref_time_counter = 0;
      	return 1;
    }
    else
    {
        key->acc_ref_time += ref_time;
        if (++key->acc_ref_time_counter >= 64)
        {
            i = key->acc_ref_time/64;
            if (i > key->base_capacitance)
               	++key->base_capacitance;
            else if (i < key->base_capacitance)
              	--key->base_capacitance;

            key->acc_ref_time = 0;
            key->acc_ref_time_counter = 0;
        }
        return 0;
    }
}

void init_key_app(key_app_data_t *key)
{
    key->key_down = 0;
    key->data = 0;
}
//
void main(void)
{
    char *LCD = LCDMEM;
    int i;

    WDTCTL = WDTPW + WDTHOLD;   	        // Stop watchdog timer
    FLL_CTL0 = XCAP18PF;            		// set load capacitance for xtal

//********************
    P1DIR = BIT0 | BIT5 | BIT6 | BIT7;
    P1OUT = 0;
    P2DIR = 0xFF;                	        // All P2.x outputs
    P2OUT = 0;                            	// All P2.x reset
    P3DIR = 0xFF;                         	// All P3.x outputs
    P3OUT = 0;                            	// All P3.x reset
    P4DIR = 0xFF;                         	// All P4.x outputs
    P4OUT = 0;                            	// All P4.x reset
    P5DIR = 0xFF;                         	// All P5.x outputs
    P5OUT = 0;                            	// All P5.x reset
    P6DIR = 0xFF;                         	// All P6.x outputs
    P6OUT = 0;                            	// All P6.x reset
//*******************

    // Initialize the LCD driver (4Mux mode)
    LCDCTL = 0x03D;             // 4mux LCD, segs16-23 = outputs
    BTCTL = BTFRFQ1;            // set LCD frame freq = ACLK
    P5SEL = 0xFC;               // set Rxx and COM pins for LCD
    LCD[7] =
    LCD[3] = 0;                 // Disconnect port pin
    TACTL = TASSEL_2 | MC_2;    // SMCLK, clear TAR
    BTCTL |= BT_ADLY_4;         // 4mS Interrupts runs off the ACLK
    IE2 |= BTIE;                // Enable BT interrupt
    _EINT();                    // Enable interrupts

    for (i = 0;  i < 10;  i++)
        LCD[i] = 0;

    for (i = 0;  i < NUM_KEYS;  i++)
    {
        init_key(&key[i], &key_config[i]);
        init_key_app(&key_app[i]);
    }

    for (;;)
    {
    	for (i = 0;  i < NUM_KEYS;  i++)
    	{
	    if (test_key(&key[i], &key_config[i]))
	    {
                if (!key_app[i].key_down)
                {
	            LCD[i] = digit[key_app[i].data];                    // On
	            if (++key_app[i].data > 9)
	                key_app[i].data = 0;
	            key_app[i].key_down = 1;
        	}
            	if (i == 0) {
                    P1OUT |= BIT0;
                    P3OUT |= BIT0;
              }
            }
            else
            {
                key_app[i].key_down = 0;
            	LCD[i] = 0;                                           	// Off
            	if (i == 0){
                    P1OUT &= ~BIT0;
                    P3OUT &= ~BIT0;
              }
            }
        }
    }
}

#pragma vector=PORT1_VECTOR
__interrupt void port_1_interrupt(void)
{
    P1IFG &= 0;                               // clear flag
    timer_count = TAR - timer_count;          // find the discharge time
    LPM0_EXIT;                                // exit from low power
}

#pragma vector=PORT2_VECTOR
__interrupt void port_2_interrupt(void)
{
    P2IFG &= 0;                               // clear flag
    timer_count = TAR - timer_count;          // find the discharge time
    LPM0_EXIT;                                // exit from low power
}

#pragma vector=WDT_VECTOR
__interrupt void wdt_interrupt(void)
{
    LPM0_EXIT;
}

#pragma vector=BASICTIMER_VECTOR
__interrupt void basictimer_interrupt(void)
{
    LPM0_EXIT;
}

⌨️ 快捷键说明

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