我試了幾次,似乎不能在定時器中斷中直接調用,可能是異步執行的問題吧,下面是一段調用該按鍵程序的參考代碼,可以參考。
////////////////PCA///////////////////////////////////
// PWM占空比值數組 (0x00=100%, 0x40=0%)
// 從最小值開始
const unsigned char ccapvalues[] = {0x38, 0x33, 0x2E, 0x25, 0x20, 0x16, 0x10, 0x00};
unsigned char ccapcounter = 0;//全局變量
void PCA_CONFIG(void){
P_SW1 = 0x10; // P3.1切換為PWM輸出
CCON = 0x00; // 復位PCA
CMOD = 0x0A; // 系統時鐘/4,6MHZ下為23.5khz
CL = 0x00; // 復位低字節
CH = 0x00; // 復位高字節
CCAPM0 = 0x42; // PCA0 PWM模式
PCA_PWM0 = 0x80;// 6位PWM模式
CCAP0H = ccapvalues[ccapcounter];//在喚醒后讀取ram中的ccapcounter值
CR = 1; //初始化不開啟電源
}
///////////////////////按鍵上層處理
bit keydet = 0;//允許按鍵檢測
unsigned char keyevent = NOKEY;//初始化為0
void KEY_HANDLER(void){
keyevent = KEY_READ();//調用按鍵讀取函數
switch(keyevent){
case LONGKEY:
poweron ^= 1;
break;
case SINGLEKEY:
if(poweron && ledmode<=2){
if(ccapcounter <= 7) ccapcounter++;//如果小于7就增加,等于7后不再增加
}
else if(poweron && ledmode>2){
if(ccapcounter <= 5) ccapcounter++;
}
break;
case DOUBLEKEY:
if(poweron && ledmode<=2){
if(ccapcounter > 0) ccapcounter--;//如果大于0就減小,等于0后不再減小
}
else if(poweron && ledmode>2){//不能寫成>=0,否則當為0時再減1...好吧這是無符號字符,不會小于0
if(ccapcounter > 0) ccapcounter--;
}
break;
case TRIPLEKEY:
switch(ledmode){
case 0:
case 1:
case 2:
if(ccapcounter == 7){
ccapcounter = 0;
}
else{
ccapcounter = 7;
}
break;
case 3:
case 4:
case 5:
if(ccapcounter == 5){
ccapcounter = 0;
}
else{
ccapcounter =5;
}
}
break;
}
}
/////////////////////定時器中斷
void TM0_ROUTINE(void) interrupt 1{//timer0中斷服務函數,20ms一次
keydet = 1;
}
|