程序写了一遍,水平有限,请指教 流程上往下,按键扫描从循环数码管输出中插入
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_(); 那里原因,谢谢
|