typedef struct{
u8 i; //;;recod scan status : line index
u8 tstatus; //temporary status of key,only the lowe nibble is valuable
u8 debounce;//debounce time
u8 status[3] ;//recod key satus,only the lowe nibble is valuable
u8 kcode; //holde the valueable key code
u16 longK; //time counter hold key
u8 hold; //flage for hold key
} KeyStru;
keyStru key;
key_init()
{Key.debounce = KeyDebounce;
Key.i = 0x00;
Key.status[0] = 0x0f;
Key.status[1] = 0x0f;
Key.status[2] = 0x0f;
Key.tstatus = 0x0f; //temporary status
Key.kcode = 00; //holde the valueable key code
Key.longK = T1000ms; //
Key.hold = 0; //flage for hold key
Key_release = 1;
Key_valid = 0;
}
/********************************************************************************
function: initial tmr0
enable tmr0 interrupt
set tmr0 circle 2ms
mode:mode 2,8bit tmr
source clock:system clock/48
C/!T = 0,Gate = 0
********************************************************************************/
void T0_Initial()
{
CKCON = 0x02; //
TL0 = 0xff-((SYSFREQ*2)/48);
TH0 = 0xff-((SYSFREQ*2)/48);
TMOD = 0x02;
TR0 = 1;
ET0 = 1;
}
/********************************************************************************
function Keyboard scan subroutine
one time scan one row
argument:void
return:keycode,00:no key valuable,8x:keyrelease,0x:key pressdown
KeyPort: check row ,KeyPort^0~KeyPort^3,input
scan column ,KeyPort^4~~KeyPort^6 ,output
p0.0-----k01---k02---k03
|| |
p0.1-----k04---k05---k06
| | | ;
p0.2-----k07---k08---k09
| | |
p0.3-----k10 | |
| | |
p0.4------+ | |
p0.5------------+ |
p0.6------------------+
k01:PowerKey;
k02:band selection;
k03:volume increase
k04:Volume-Dec
k05:tuneUp/SeekUp
k06:tuneDown/seekDown
k07:AutoScan all station and save them/select the item of timer for set/select function to up
k08:select the preset station forward /change the selected item of timer forward /change selected function forward
k09:select the preset station backward /change the selected item of timer backward /change selected function backward
k10:select the function that will be change/enter set time mode
********************************************************************************/
//u8 KeyCode()
/****************************************************************************************
function:TMR0 isr interrupt,number 1,vector 0x0b
delay time counter
****************************************************************************************/
void Isr_Tmr0() interrupt 1
{
u8 in;
KeyPort = outlist[Key.i]; //get initial output code
_nop_();
in = KeyPort &0x0f;
KeyPort = 0xff;//reset port status
if(in == Key.status[Key.i])//Key on the current line have no change
{
if(Key.i == MaxKeyLin-1)
{
Key.i = 0;
}
else
Key.i++;//ready for scanning next line
//-----------------------------------------------------
if(Key_release)
return;
Key.longK--;
if(Key.longK)
return;
switch(Key.kcode)
{
case VOLINC_KEY: //only have long-key function or short-key mode
case VOLDEC_KEY:
if(Key.hold==0)
{
Key.hold = 2; //long-key mode
Key.longK = T1000ms; //leave short-key mode to middle-key mode
return;
}
break;
case TUNEUP_KEY:
case TUNEDOWN_KEY://have all three mode
if(Key.hold == 0)
{
Key.longK = T1000ms; //leave short-key mode to middle-key mode
Key.hold++;
return;
}
if(Key.hold == 1)
Key.hold++;
break ;
default:
return ;//only have short-key mode
}
Key.longK = T250ms;
Key_valid = 1;
return;
}
if(in != Key.tstatus) //Key is change,but is not equal to last status
{
Key.tstatus = in;
return;
}
if(Key.debounce--)
return;
Key.debounce = KeyDebounce;
in ^= Key.status[Key.i]; //get changed key
Key.status[Key.i] = Key.tstatus;//save new status
Key.kcode = (codelist[in]) + (Key.i<<2); //caculate the code of the key which is changed
in = masklist[in]; //check push or release
if(in & Key.tstatus)
{
Key_release = 1;
Key_valid = 1;
if(Key.hold ==1) //middle key
Key.kcode+=0x80;
return;
}
else
{
if(Key.kcode == 0x01)
fCombination = 1;
Key.hold = 0; //a new button pushed
Key.longK = T1000ms; //1 second
Key_release = 0;
return ;
}
}