📄 f413 touchpad demo general.c
字号:
//*****************************************************************************
#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 + -