#include "key.h"
volatile __data u16 irData;
volatile __data u8 irState = 0;
volatile __data u8 key_value;
//volatile __data u16 irCounter;
extern void PutMsg(u8 msg);
#define TIMER1_PRESCAL 128 //32
#define userCode 0x02
#pragma constseg=IR_CONST_TABLE
#if 0
const u8 irTable[32] =
{
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
T_KEY_PLAY, T_KEY_CH_DOWN, T_KEY_CH_UP, NO_KEY, T_KEY_EQ_UP, T_KEY_VOL_DOWN, T_KEY_VOL_UP, NO_KEY, T_KEY_0, T_KEY_PREV_FILE, T_KEY_NEXT_FILE, NO_KEY, T_KEY_1, T_KEY_2, T_KEY_3, NO_KEY,
T_KEY_4, T_KEY_5, T_KEY_6, NO_KEY, T_KEY_7, T_KEY_8, T_KEY_9, NO_KEY, T_KEY_PICK_SONG, NO_KEY, T_KEY_PICK_CH, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY
};
#else
const u8 irTable[96] =
{
NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, T_KEY_VOL_DOWN, T_KEY_4, T_KEY_EQ_UP, NO_KEY, NO_KEY, T_KEY_1, T_KEY_NEXT_FLOD, NO_KEY, NO_KEY,
NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, T_KEY_VOL_UP, T_KEY_0, NO_KEY, T_KEY_2, T_KEY_100N, NO_KEY, NO_KEY, T_KEY_5, NO_KEY, NO_KEY, NO_KEY,
NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY,
NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY,
T_KEY_NEXT_FILE, NO_KEY, T_KEY_7, T_KEY_PLAY, T_KEY_PREV_FILE, T_KEY_CH_DOWN, T_KEY_PICK_CH, T_KEY_CH_UP, NO_KEY, NO_KEY, T_KEY_9, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY,
NO_KEY, NO_KEY, T_KEY_8, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, NO_KEY, T_KEY_6, NO_KEY, NO_KEY, NO_KEY, T_KEY_3, NO_KEY,
};
#endif
#pragma constseg=default
/*******************************************************************************************
Function Name:
Discription:
Input parameter:
Return parameter:
Caution:
*******************************************************************************************/
#pragma vector = VECTOR_OFFSET(TIMER1_INT)
#pragma register_bank = 2
__interrupt void ISR_timer1(void)
{
u8 counter;
u16 irCounter;
asm("PUSH DPS");
DPS &= 0xC0;
if (TMR1CON1 & 0x40) //CAPTURE
{
TMR1CNTL = 0;
TMR1CNTH = 0;
irCounter = TMR1PWMH<<8;
u8 aa = TMR1PWML;
irCounter |= aa;
TMR1CON1 &= ~BIT(6);
irCounter /= ( 48000 / TIMER1_PRESCAL );
}
else //overflow
{
TMR1CON1 &= ~BIT(7);
irCounter = 0;
}
counter = irCounter;
if (((counter > 5) && (counter < 15)) || ((counter > 30) && (counter < 50)) || ((counter > 90) && (counter < 100)))
{
asm("POP DPS");
return;
}
irData >>= 1;
irState++;
if (counter == 2)
{
irData |= 0x8000;
}
else if (counter == 1)
{
asm("POP DPS");
return;
}
else
{
irState = 0;
irData = NO_KEY;
}
if (irState == 32)
{
if ((irData&0xFF)>=96)
{
irState = 0;
irData = NO_KEY;
}
}
asm("POP DPS");
}
/*******************************************************************************************
Function Name:KeyDetect
Discription: AD key检测
Input parameter:
Return parameter:
Caution:
为了使按键的接触电阻对检测影响少,重新分配了ADKEY的电阻值,对应标准开发板的原理图,分别为:
电阻 阻值 对应电压 对应检测值 ADCDATAH
R110 100K 0 0 0
R111 15K 0.407 0x85 0x21
R112 18K 0.775 0xfe 0x3f
R113 27K 1.172 0x180 0x60
R114 36K 1.531 0x1f5 0x7d
R115 68K 1.942 0x27c 0x9f
R116 150K 2.371 0x308 0xc2
R117 470K 2.773 0x38c 0xe3
*******************************************************************************************/
static u8 KeyDetect(void)
{
u8 keyTmp = NO_KEY;
if (irState == 32)
{
keyTmp = irTable[irData & 0xff];
}
else if ( !( ADCCON & (1<<7) ) )
{
u8 tmp = ADCDATAH;
//tmp >>= 4;
//keyTmp = ADKeyTable[tmp];
if (tmp < 0x15)
keyTmp = T_KEY_PREV_FILE;
else if (tmp < 0x39)
keyTmp = T_KEY_PLAY;
else if (tmp < 0x5A)
keyTmp = T_KEY_NEXT_FILE;
else if (tmp < 0x77)
keyTmp = T_KEY_VOL_DOWN;
else if (tmp < 0x99)
keyTmp = T_KEY_VOL_UP;
else if (tmp < 0xbc)
keyTmp = T_KEY_PICK_CH;
//play fast set
//else if (tmp < 0xdd)
else if (tmp < 0xc5)
keyTmp = T_KEY_MINUS;//fast backward
else if (tmp < 0xf0)
keyTmp = T_KEY_PLUS;//fast forward
ADCCON |= ( 1<<7 );
}
return keyTmp;
}
/*******************************************************************************************
Function Name:
Discription:
Input parameter:
Return parameter:
Caution: 此函数需每5ms调用一次
*******************************************************************************************/
void KeyScan(void)
{
static __idata u8 keyValue,keyCounter,secCounter;
u8 keyTmp,key_return = NO_KEY;
secCounter++;
if (secCounter == (500 / 5))
{
secCounter = 0;
PutMsg(KEY_HALF_SEC);
}
keyTmp = KeyDetect();
if (keyTmp == NO_KEY) //抬键或者没有按键
{
if (long_key == TRUE) //长按抬键
key_return = keyValue | TASK_KEY_LONG_UP;
else if ((keyCounter < KEY_LONG_TIMES ) && (keyCounter > KEY_SCAN_TIMES)) //短按抬键
key_return = keyValue | TASK_KEY_SHORT_UP;
keyValue = NO_KEY;
long_key = 0;
keyCounter = 0;
}
else if (keyTmp != keyValue)
{
keyValue = keyTmp;
keyCounter = 0;
long_key = 0;
}
else
{
keyCounter++;
if (keyCounter == KEY_SCAN_TIMES) //去抖
{
key_return = keyValue;
}
else if (keyCounter == KEY_LONG_TIMES ) //长按
{
if (long_key == FALSE)
{
long_key = TRUE;
key_return = keyValue | TASK_KEY_LONG;
}
}
else if (keyCounter == (KEY_LONG_TIMES + KEY_HOLD_TIMES) ) //连按
{
key_return = keyValue | TASK_KEY_HOLD;
keyCounter = KEY_LONG_TIMES;
}
}
if ( key_return != NO_KEY)
PutMsg(key_return);
}