3楼回答了。
delayMs(1)产生一个1ms的时基.
利用1ms的时基,产生100ms的时基,100ms的时基控制LED,如果觉得100ms不够实时,可以再小些。
利用1ms的时基,产生50ms的时基,用于检测按键。
实时是相对的,除了实时钟,和很高速的运用外,1ms的时基派生出来的时基足够大多数数运用,如LED扫描2ms,按键50ms, 马达PWM调速等。
下面是参考,未经过验证,细节不一对(有问题请指正),但大概意思是这样,函数之间尽可能的减少瓜葛,自己产生的标志自己消灭掉。
带F的是位标志,带d的是变量,Io的是Io口。LED高电平亮。按键是按下=0.
GetClock()
{ F_Clk100ms=0;
F_Clk50ms=0;
delayMs(1);
if(++dCntClk1>=100) {dCntClk1=0;F_Clk100ms=1;}
if(++dCntClk2>=50) {dCntClk2=0;F_Clk50ms=1;}
}
GetKey()
{ F_KeyAPush=0;
F_KeyBPush=0;
if(!F_Clk50ms) return;
if(F_KeyAlast!=Io_KeyA) {F_KeyAlast=Io_KeyA;
if(F_KeyAlast==0) F_KeyAPush=1;
}
if(F_KeyBlast!=Io_KeyB) {F_KeyBlast=Io_KeyB;
if(F_KeyBlast==0) F_KeyBPush=1;
}
}
RunLEDA()
{ if(F_KeyAPush==1) { F_LEDA_Enb=!F_LEDA_Enb;
if(F_LEDA_Enb==1) {dCntLedA=0;Io_LEDA=1;}
}
if(F_LEDA_Enb==0) {Io_LEDA=0;return;}
if(!F_Clk100ms) return;
if(++dCntLedA>=20) {Io_LEDA=1;dCntLedA=0;}
if(dCntLedA==6) Io_LEDA=0;
}
RunLEDB()
{ if(F_KeyBPush==1) { F_LEDB_Enb=!F_LEDB_Enb;
if(F_LEDB_Enb==1) {dCntLedB=0;Io_LEDB=1;}
}
if(F_LEDB_Enb==0) {Io_LEDB=0;return;}
if(!F_Clk100ms) return;
if(++dCntLedB>=10) {Io_LEDB=1;dCntLedB=0;}
if(dCntLedB==6) Io_LEDB=0;
}
while(1)
{ GetClock();
Getkey();
RunLEDA();
RunLEDB();
}
|