程序寫了一遍,水平有限,請指教 流程上往下,按鍵掃描從循環數碼管輸出中插入
bit key_service_Lock=0; //循環標志位,禁止連續掃描
uchar KeySec = 0; //按鍵編號
uchar KeyTimeCnt=0; //按鍵去抖動延時計數器
uchar key_service_tmp;
while(1)
{
void Reuse_time_sharing() //復用驅動數碼管 此函數通用定時器標位控制,1MS循環一次,每次約15MS
{
if(Reuse)
{
Reuse=~Reuse;
Reuse_count++;
switch(Reuse_count)
{
case 1 : //DS1_1 第一個數碼管個位
P05=0; //關閉上一個輸出位選
if(!key_service_Lock) //循環標志位0,進入掃描按鍵
key_select(); //掃描按鍵函數
P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,1)]; //輸出段選
P03=1; //打開位選
break;
case 2 : //DS1_10
P03=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,1)];
P04=1;
break;
case 3 : //DS2_1
P04=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,1)];
P02=1;
break;
case 4 : //DS2_10
P02=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,10)];
P47=1;
break;
case 5 : //DS3_1
P47=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_A,1)];
P01=1;
break;
case 6 : //DS3_10
P01=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_A,10)];
P00=1;
break;
case 7 : //DS4_1 time
P00=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_456[Energy_TXD(Time_MIN,1)];
P37=1;
break;
case 8: //DS4_10 time
P37=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_456[Energy_TXD(Time_MIN,10)];
P41=1;
break;
case 9 : //DS5_1
P41=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_B,1)];
P36=1;
break;
case 10 : //DS5_10
P36=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_B,10)];
P43=1;
break;
case 11 : //DS6_1
P43=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_A,1)];
P45=1;
break;
case 12: //DS6_10
P45=0;
if(!key_service_Lock)
key_select();
P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_A,10)];
P44=1;
break;
case 13 : //D1~D8
P44=0;
if(!key_service_Lock)
key_select();
if(Ion_mode==0)
P2=0xfb;
else if(Ion_mode==1)
P2=0xfd;
else
P2=0xfe;
P11=1;
break;
case 14 : //D19~D16
P11=0;
if(!key_service_Lock)
key_select();
if(start_Time)
P2=0xf7;
else P2=0xff;
P42=1;
break;
case 15 : //D17~D21
P42=0;
if(!key_service_Lock)
key_select();
P05=1;
break;
default:break;
}
if(Reuse_count>=15)
Reuse_count=0;
}
}
} //大循環到止
void key_select() //按鍵掃描函數
{
uchar i;
Bidirectional_IO(); //P46,P13,P15 設用準雙口
for(i=1;i<=8;i++)
{
switch(i) //按鍵服務狀態切換
{
case 1: P2=0x7f; //掃描按鍵 復用IO輸出O
_nop_(); //這里不加空操作,會讀不到
_nop_();
if(P13==0) //判斷IO是否拉低
{KeySec =7; key_service_Lock=~key_service_Lock;return;} //緩存對應按鍵 ,循環標志位取反,放開TO內部函數
else if(P46==0) //判斷IO是否拉低
{KeySec =12; key_service_Lock=~key_service_Lock;return;} //緩存對應按鍵 ,循環標志位取反,
break;
case 2: P2=0xbf;
if(P13==0)
{KeySec =9; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =1;key_service_Lock=~key_service_Lock;return;}
break;
case 3: P2=0xdf;
if(P13==0)
{KeySec =8; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =3; key_service_Lock=~key_service_Lock;return;}
break;
case 4: P2=0xef;
if(P13==0)
{KeySec =5; key_service_Lock=~key_service_Lock;return;}
else if(P15==0)
{KeySec =18; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =14; key_service_Lock=~key_service_Lock;return;}
break;
case 5: P2=0xf7;
if(P13==0)
{KeySec =6; key_service_Lock=~key_service_Lock;return;}
else if(P15==0)
{KeySec =17; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =4; key_service_Lock=~key_service_Lock;return;}
break;
case 6: P2=0xfb;
if(P15==0)
{KeySec =15; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =2; key_service_Lock=~key_service_Lock;return;}
break;
case 7: P2=0xfd;
if(P15==0)
{KeySec =19; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =13; key_service_Lock=~key_service_Lock;return;}
break;
case 8: P2=0xfe;
if(P15==0)
{KeySec =16; key_service_Lock=~key_service_Lock;return;}
else if(P46==0)
{KeySec =11; key_service_Lock=~key_service_Lock;return;}
break;
default: break;
}
}
High_IO(); //P46,P13,P15 設用高阻
}
void TM0_Isr() interrupt 1 //定時器0中斷
{
if(!Reuse)
Reuse=~Reuse;
if(key_service_Lock) //循環標志位取反,進入中斷
{
KeyTimeCnt++;
if(KeyTimeCnt>=20) //大于20Ms
{ P0&=0xc0; //拉低循環過程中位選
P11=0; //拉低循環過程中位選
P3&=0x1f; //拉低循環過程中位選
P4&=0x43; //拉低循環過程中位選
KeyTimeCnt=0;
key_service_Lock=~key_service_Lock; ////循環標志位取反,防止進入中斷,開放循環掃描
key_service_tmp=KeySec; //緩存上次掃描結果
key_select(); //再次掃描
if(key_service_tmp==KeySec) //對比掃描結果
{
key_service(); //調用按鍵服務程序
}
//else KeySec=0;
P0|=0xc0;
P11=1;
P3|=0x1f;
P4|=0x43;
}
}
}
請問怎么優化,還有_nop_(); 那里原因,謝謝
|