<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                【89.1 跑馬燈的三種境界。】 跑馬燈也稱為流水燈,排列的幾個LED依次循環的點亮和熄滅,給人“跑動起來”的感覺,故稱為“跑馬燈”。實現跑馬燈的效果,編程上有三種思路,分別代表了跑馬燈的三種境界,分別是:移位阻塞,移位非阻塞,狀態切換非阻塞。 ![](https://img.kancloud.cn/0f/49/0f49cc4e7b34f0e8c13dd7e514906c88_214x279.png) 圖89.1.1 灌入式驅動8個LED 本節用的是8個LED燈依次挨個熄滅點亮,如上圖所示。 【89.2 移位阻塞。】 移位阻塞,“移位”用的是C語言的左移或者右移語句,“阻塞”用的是delay延時。代碼如下: \#include "REG52.H" void T0\_time(); void SystemInitial(void) ; void Delay(unsigned long u32DelayTime) ; void PeripheralInitial(void) ; void LedTask(void); void main() { SystemInitial(); Delay(10000); PeripheralInitial(); while(1) { LedTask(); } } void T0\_time() interrupt 1 { TH0=0xfc; TL0=0x66; } void SystemInitial(void) { TMOD=0x01; TH0=0xfc; TL0=0x66; EA=1; ET0=1; TR0=1; } void Delay(unsigned long u32DelayTime) { for(;u32DelayTime>0;u32DelayTime--); } void PeripheralInitial(void) { } //跑馬燈的任務程序 void LedTask(void) { static unsigned char Su8Data=0x01; //加static修飾的局部變量,每次進來都會保留上一次值。 static unsigned char Su8Cnt=0; //加static修飾的局部變量,每次進來都會保留上一次值。 P0=Su8Data; //Su8Data的8個位代表8個LED的狀態,0為點亮,1為熄滅。 Delay(10000) ; //阻塞延時 Su8Data=Su8Data<<1; //左移一位 Su8Cnt++; //計數器累加1 if(Su8Cnt>=8) //移位大于等于8次后,重新賦初值 { Su8Cnt=0; Su8Data=0x01; //重新賦初值,繼續下一次循環移動 } } 分析總結:這是第1種境界的跑馬燈,這種思路雖然實現了跑馬燈的效果,但是因為“阻塞延時”,整個程序顯得僵硬機械,缺乏多任務并行的框架。 【89.3 移位非阻塞。】 移位非阻塞,“移位”用的是C語言的左移或者右移語句,“非阻塞”用的是定時中斷衍生出來的軟件定時器。代碼如下: \#include "REG52.H" void T0\_time(); void SystemInitial(void) ; void Delay(unsigned long u32DelayTime) ; void PeripheralInitial(void) ; void LedTask(void); \#define BLINK\_TIME\_1 1000 volatile unsigned char vGu8TimeFlag\_1=0; volatile unsigned int vGu16TimeCnt\_1=0; void main() { SystemInitial(); Delay(10000); PeripheralInitial(); while(1) { LedTask(); } } void T0\_time() interrupt 1 { if(1==vGu8TimeFlag\_1&&vGu16TimeCnt\_1>0) //軟件定時器 { vGu16TimeCnt\_1--; } TH0=0xfc; TL0=0x66; } void SystemInitial(void) { TMOD=0x01; TH0=0xfc; TL0=0x66; EA=1; ET0=1; TR0=1; } void Delay(unsigned long u32DelayTime) { for(;u32DelayTime>0;u32DelayTime--); } void PeripheralInitial(void) { } //跑馬燈的任務程序 void LedTask(void) { static unsigned char Su8Data=0x01; //加static修飾的局部變量,每次進來都會保留上一次值。 static unsigned char Su8Cnt=0; //加static修飾的局部變量,每次進來都會保留上一次值。 if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0=Su8Data; //Su8Data的8個位代表8個LED的狀態,0為點亮,1為熄滅。 Su8Data=Su8Data<<1; //左移一位 Su8Cnt++; //計數器累加1 if(Su8Cnt>=8) //移位大于等于8次后,重新賦初值 { Su8Cnt=0; Su8Data=0x01; //重新賦初值,繼續下一次循環移動 } } } 分析總結:這是第2種境界的跑馬燈,這種思路雖然實現了跑馬燈的效果,也用到了多任務并行處理的基本元素“軟件定時器”,但是因為還停留在“移位”語句的階段,此時的程序并沒有超越跑馬燈本身,跑馬燈還是跑馬燈,處于“看山還是山”的境界。 【89.4 狀態切換非阻塞。】 狀態切換非阻塞,“狀態切換”用的是switch語句中根據特定條件進行步驟切換,“非阻塞”用的是定時中斷衍生出來的軟件定時器。代碼如下: \#include "REG52.H" void T0\_time(); void SystemInitial(void) ; void Delay(unsigned long u32DelayTime) ; void PeripheralInitial(void) ; void LedTask(void); \#define BLINK\_TIME\_1 1000 sbit P0\_0=P0^0; sbit P0\_1=P0^1; sbit P0\_2=P0^2; sbit P0\_3=P0^3; sbit P0\_4=P0^4; sbit P0\_5=P0^5; sbit P0\_6=P0^6; sbit P0\_7=P0^7; volatile unsigned char vGu8TimeFlag\_1=0; volatile unsigned int vGu16TimeCnt\_1=0; void main() { SystemInitial(); Delay(10000); PeripheralInitial(); while(1) { LedTask(); } } void T0\_time() interrupt 1 { if(1==vGu8TimeFlag\_1&&vGu16TimeCnt\_1>0) //軟件定時器 { vGu16TimeCnt\_1--; } TH0=0xfc; TL0=0x66; } void SystemInitial(void) { TMOD=0x01; TH0=0xfc; TL0=0x66; EA=1; ET0=1; TR0=1; } void Delay(unsigned long u32DelayTime) { for(;u32DelayTime>0;u32DelayTime--); } void PeripheralInitial(void) { } //跑馬燈的任務程序 void LedTask(void) { static unsigned char Su8Step=0; //加static修飾的局部變量,每次進來都會保留上一次值。 switch(Su8Step) { case 0: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=1; //第0個燈熄滅 P0\_1=0; P0\_2=0; P0\_3=0; P0\_4=0; P0\_5=0; P0\_6=0; P0\_7=0; Su8Step=1; //切換到下一個步驟,精髓語句! } break; case 1: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=1; //第1個燈熄滅 P0\_2=0; P0\_3=0; P0\_4=0; P0\_5=0; P0\_6=0; P0\_7=0; Su8Step=2; //切換到下一個步驟,精髓語句! } break; case 2: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=0; P0\_2=1; //第2個燈熄滅 P0\_3=0; P0\_4=0; P0\_5=0; P0\_6=0; P0\_7=0; Su8Step=3; //切換到下一個步驟,精髓語句! } break; case 3: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=0; P0\_2=0; P0\_3=1; //第3個燈熄滅 P0\_4=0; P0\_5=0; P0\_6=0; P0\_7=0; Su8Step=4; //切換到下一個步驟,精髓語句! } break; case 4: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=0; P0\_2=0; P0\_3=0; P0\_4=1; //第4個燈熄滅 P0\_5=0; P0\_6=0; P0\_7=0; Su8Step=5; //切換到下一個步驟,精髓語句! } break; case 5: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=0; P0\_2=0; P0\_3=0; P0\_4=0; P0\_5=1; //第5個燈熄滅 P0\_6=0; P0\_7=0; Su8Step=6; //切換到下一個步驟,精髓語句! } break; case 6: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=0; P0\_2=0; P0\_3=0; P0\_4=0; P0\_5=0; P0\_6=1; //第6個燈熄滅 P0\_7=0; Su8Step=7; //切換到下一個步驟,精髓語句! } break; case 7: if(0==vGu16TimeCnt\_1) //時間到 { vGu8TimeFlag\_1=0; vGu16TimeCnt\_1=BLINK\_TIME\_1; //重裝定時的時間 vGu8TimeFlag\_1=1; P0\_0=0; P0\_1=0; P0\_2=0; P0\_3=0; P0\_4=0; P0\_5=0; P0\_6=0; P0\_7=1; //第7個燈熄滅 Su8Step=0; //返回到第0個步驟重新開始往下走,精髓語句! } break; } } 分析總結:這是第3種境界的跑馬燈,很多初學者咋看此程序,表示不理解,人家一條賦值語句就解決8個LED一次性顯示的問題,你非要拆分成8條按位賦值的語句,人家只用一個判斷就實現了LED燈移動顯示的功能,你非要整出8個步驟的切換,況且,整個程序的代碼量明顯增加了很多,這個程序好在哪?其實,我這么做是用心良苦呀。這個程序的代碼量雖然增多了,但是仔細一看,并沒有影響運行的效率。之所以把8個LED燈拆分成一個一個的LED燈單獨賦值顯示,是因為,在我眼里,這個8個LED燈代表的不僅僅是LED燈,而是8個輸出信號!這8個輸出信號未來驅動的可能是不同的繼電器,氣缸,電機,大炮,導彈,以及它們的各種千變萬化的組合邏輯,拆分之后程序框架就有了無限可能的擴展性。之所以整出8個步驟的切換,也是同樣的道理,為了增加程序框架無限可能的擴展性。這個程序雖然表面看起來繁瑣,但是仔細一看它是“多而不亂”,非常富有“隊形感”。因此可以這么說,這個看似繁瑣的跑馬燈程序,其實背后蘊藏了編程界的大智慧,它已經突破了“看山還是山”的境界。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看