📄 f413 touchpad demo general.c
字号:
long min;
long max;
int idx;
int max_pos;
int i;
min = 32767;
max = -32768;
max_pos = -1;
//search for the pad with the highest number
//that is used later for the weighed average calculation
for (i = 0; i < NUM_SCROLL_KEYS; i++)
{
if (key[i].filtered < min)
min = key[i].filtered;
if (key[i].filtered > max)
{
max = key[i].filtered;
max_pos = i;
}
}
if (max < key_threshold) //if the maximum score is below a threshold, we report
{ // ad adaptation here is key is on pressed
for (i = 0; i < NUM_SCROLL_KEYS; i++)
{
if(key[i].filtered>0) //accelarte the downward slope
key[i].adapt+=8;
else
key[i].adapt+=-2;
//filter has 16 gain so threshold is min 16
//increase hysteresis margins
if(key[i].adapt>320)
{
++key[i].base_capacitance;
key[i].adapt=0;
key[i].adapt_flag=10;
}
else if(key[i].adapt<-320)
{
--key[i].base_capacitance;
key[i].adapt=0;
key[i].adapt_flag=100;
}
else
key[i].adapt_flag=0;
}
return -1; //no key-press
}
/* We have a finger */
//
//Do weighed average to interpolate between pads. This algorithm would output
// a number between 1-256
//This does not work well the maximum is near the end stops
//So we look at the keypressed and do the sequence and:
// If the pad is between 4 and 12, the sequence starts from 0->15
// Otherwise the sequence starts from 8->15->7
max>>=3; //threshold = max/8
#if SQUARE
if (max_pos >= 0 && max_pos <= 11)
#else
if (max_pos >= 3 && max_pos <= 9)
#endif
// if (max_pos >= 3 && max_pos <= 9)
{
/* The finger is somewhere in the central area of the sequence, so do the linear weighted average from 1->16 */
a = 0;
b = 0;
for (i = 0; i < NUM_SCROLL_KEYS; i++)
{
if(key[i].filtered>=max)
{
a += (key[i].filtered);
b += (i + 1)*(key[i].filtered);
}
}
b /= (a >>4);
if (b < 0)
b = 0;
}
else
{
/* The finger is somewhere in the join between 16 and 1, so do the linear weighted average from 9->16->1->8 */
a = 0;
b = 0;
for (i = 0; i < NUM_SCROLL_KEYS; i++)
{
idx=(i + 8) & 15;
if(key[idx].filtered>=max)
{
a += (key[idx].filtered);
b += (i + 1)*(key[idx].filtered);
}
}
b /= (a >>4);
if (b < 0)
b = 0;
else
b = (b + 128) & 0xFF;
}
//b = max;
return (int) b;
}
void queue_key(int key)
{
if(key<0) key=0;
if(key>255) key=255; //stop the display from doing spikes
key_queue[key_in] = key;
if (++key_in >= 8)
key_in = 0;
}
int last_position = 0;
int filtered = 0;
int button_down = 0;
void main(void)
{
unsigned int i,no_key_count;
unsigned int k;
unsigned int q,r;
// int margin;
// Stop the watchdog timer
WDTCTL = WDTPW + WDTHOLD;
// We must turn off the low frequency crystal oscillator, as we are using its pins as I/O pins
//_BIS_SR(OSCOFF);
FLL_CTL0 |= XCAP18PF;
SCFI0 |= FN_4;
SCFQCTL = 121;
for(i=0;i<2500;i++);
// Initially discharge all the touchpad pins
P1OUT = 0;
P1DIR = 0xFF;
P1SEL = 0;
P2OUT = 0;
P2DIR = 0xFF;
P2SEL = 0;
// P3SEL = 0;
// P3DIR = 0xff;
P4SEL = 0;
P4DIR = 0xff;
P6OUT=0X00;
P6DIR=0XFF;
key_in = 0;
key_out = 0;
#if SQUARE //如果当前键盘是条形键盘
key_threshold=280;
#elif RECTANGLE
key_threshold=200;
#else //如果当前键盘是圆环形键盘
key_threshold=90;
#endif
#if OUTPUT_I2C
i2c_config();
#endif
LCDCTL = LCDON+LCD4MUX+LCDSG0_1; // LCD ON+(4 MUX+LCD SEG ON)+S0~S15
BTCTL = BT_fLCD_DIV64; // 扫描频率率 32768/64=512 桢率 64
P5SEL = 0xFC; //端口五,选用复用功能
for(i=0;i<8;i++)
{
LCDMEM[i]=0;
}
// SMCLK, clear TAR
TACTL = TASSEL_2 | MC_2;
_EINT();
// Initialise all the keys
for (i = 0; i < NUM_KEYS; i++)
init_key(&key[i], &key_config[i]);
// Do the scan quite a few times, to allow time for the MCLK to stablise
for (k = 0; k < 100; k++)
scan_keys();
for (i = 0; i < NUM_KEYS; i++)
{
key[i].base_capacitance = key[i].filtered >> 4;
key[i].filtered = 0;
}
snapshot = key[2].filtered;
for (i = 0; i < 20; i++)
stuff[i] = 0;
stuffp = 0;
stuffpx = 0;
q=r=0;
for (;;)
{
scan_keys();
filtered = find_mean_position();
if (filtered >= 0)
{
no_key_count=0;
/* Turn on green LED while touching */
// P4OUT &= ~BIT4;
if (filtered > last_position + 6
||
filtered < last_position - 6)
{
if (filtered > last_position)
last_position = filtered - 5;
else
last_position = filtered + 5;
#if SQUARE
if(filtered>=191)
filtered = 191;
#endif
LCDMEM[0]=digit[( unsigned char)filtered % 10];
LCDMEM[1]=digit[((unsigned char)filtered /10) % 10];
LCDMEM[2]=digit[((unsigned char)filtered /100) % 10];
Uart_Tx(filtered);
}
else
{
//for(i=0;i<8;i++)
// {
//LCDMEM[i]=0;
// } //Buzzer
}
}
else
{
last_position = -100;
/* Turn off the LEDs */
for(i=0;i<8;i++)
{
LCDMEM[i]=0;
}
#if LOW_POWER
if(++no_key_count>4000)
{
P4OUT &= ~(BIT3+BIT5);
no_key_count=low_power_counter=0;
for(i=0;i<8;i++)
{
LCDMEM[i]=0;
}
}
#endif
}
}
}
#pragma vector=PORT1_VECTOR
__interrupt void port_1_interrupt(void)
{
P1IFG = 0; // clear flag
timer_count = TAR - timer_count; // find the discharge time
LPM3_EXIT; // exit from low power 3 or 0
}
#pragma vector=PORT2_VECTOR
__interrupt void port_2_interrupt(void)
{
P2IFG = 0; // clear flag
timer_count = TAR - timer_count; // find the discharge time
LPM3_EXIT; // exit from low power
}
#pragma vector=TIMERA1_VECTOR
__interrupt void timera1_interrupt(void)
{
switch (TAIV)
{
case 2:
/* TACCR1 */
LPM3_EXIT;
break;
}
}
// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
unsigned char i;
for(i=0;i<8;i++)
{
LCDMEM[i]=0;
}
}
//=========================================
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
switch(tx_bit)
{
case 1: CCR0 = 209;break;
case 2: CCR0 = 208;break;
case 3: CCR0 = 208;break;
case 4: CCR0 = 208;break;
case 5: CCR0 = 208;break;
case 6: CCR0 = 208;break;
case 7: CCR0 = 208;break;
case 8: CCR0 = 209;break;
default:break;
}
if(tx_bit==0)
{
P6OUT =0X00;
CCR0 =209;
tx_bit++;
}
else
{
if(tx_bit<9)
{
P6OUT=reg_tx & 0X01;
reg_tx >>=1;
tx_bit++;
}
else
{
P6OUT=0X01;
CCR0=65000;
LPM0_EXIT;
tx_bit=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -