<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 功能強大 支持多語言、二開方便! 廣告
                【121.1 可調參數的數碼管倒計時。】 ![](https://img.kancloud.cn/d1/98/d19803e327fa494dce4ab72902e02129_285x371.png) 上圖121.1.1 數碼管 ![](https://img.kancloud.cn/a2/3d/a23df87ac21f61d2182864f67461b009_359x103.png) 上圖121.1.2 獨立按鍵 ![](https://img.kancloud.cn/89/70/8970513a066fe0726b2997dcb0329ce0_194x190.png) 上圖121.1.3 有源蜂鳴器 上節講如何設置數據,本節講“數據”如何關聯“某種功能”,本節的“可調參數”就是“數據”,“倒計時”就是“某種功能”。程序功能如下: (1)倒計時范圍從0.00秒到99.99秒,范圍可調。開機默認是:10.00秒。 (2)K1[設置鍵]。當數碼管“沒有閃爍”時,“長按”K1鍵則進入“閃爍模式”,某位數碼管開始閃爍,閃爍的位代表可修改的位數據,此時再“短按”K1按鍵可以使數碼管在位之間切換閃爍。當數碼管處于“閃爍模式”時,“長按”K1按鍵,代表數據修改完成并停止閃爍。 (3)K2[加鍵]與[復位健]。當數碼管某位正在閃爍時,此時K2是[加鍵],按K2會使位數據“自加1”。當數碼管“沒有閃爍”時,此時K2是[復位鍵],按K2會使當前倒計時數據恢復“設置值”。 (4)K3[減鍵]與[開始健]。當數碼管某位正在閃爍時,此時K3是[減鍵],按K3會使位數據“自減1”。當數碼管“沒有閃爍”時,此時K3是[開始鍵],按K3開始倒計時。 代碼如下: \#include "REG52.H" \#define KEY\_FILTER\_TIME 25 //按鍵的“短按”兼“濾波”的“穩定時間” \#define KEY\_LONG\_TIME 500 //按鍵的“長按”兼“濾波”的“穩定時間” \#define SCAN\_TIME 1 \#define VOICE\_TIME 50 \#define BLINK\_TIME 250 //數碼管閃爍跳動的時間的間隔 void T0\_time(); void SystemInitial(void) ; void Delay(unsigned long u32DelayTime) ; void PeripheralInitial(void) ; void KeyScan(void); void KeyTask(void); void VoiceScan(void); void DisplayScan(void); void DisplayTask(void); //上層顯示的任務函數 void RunTask(void); //倒計時的應用程序 void Wd1(void); //窗口1顯示函數。用來設置參數。 void Wd2(void); //窗口2顯示函數。倒計時的運行顯示窗口 void PartUpdate(unsigned char u8Part); //局部選擇對應的某個局部變量更新顯示輸出 void BeepOpen(void); void BeepClose(void); sbit KEY\_INPUT1=P2^2; sbit KEY\_INPUT2=P2^1; sbit KEY\_INPUT3=P2^0; sbit P1\_0=P1^0; sbit P1\_1=P1^1; sbit P1\_2=P1^2; sbit P1\_3=P1^3; sbit P3\_4=P3^4; //數碼管轉換表 code unsigned char Cu8DigTable\[\]= { 0x3f, //0 序號0 0x06, //1 序號1 0x5b, //2 序號2 0x4f, //3 序號3 0x66, //4 序號4 0x6d, //5 序號5 0x7d, //6 序號6 0x07, //7 序號7 0x7f, //8 序號8 0x6f, //9 序號9 0x00, //不顯示 序號10 0x40, //橫杠- 序號11 }; volatile unsigned char vGu8ScanTimerFlag=0; volatile unsigned int vGu16ScanTimerCnt=0; volatile unsigned char vGu8BeepTimerFlag=0; volatile unsigned int vGu16BeepTimerCnt=0; volatile unsigned char vGu8BlinkTimerFlag=0; //數碼管閃爍跳動的定時器 volatile unsigned int vGu16BlinkTimerCnt=0; //倒計時的軟件定時器,注意,這里是unsigned long類型,范圍是0到4294967295毫秒 volatile unsigned char vGu8CountdownTimerFlag=0; volatile unsigned long vGu32CountdownTimerCnt=10000; //當前倒計時的計時值 unsigned long Gu32SetData\_Countdown=10000; //倒計時的設置值 //數碼管上層每10ms就定時刷新一次顯示的軟件定時器。用于及時更新顯示秒表當前的實時數值 volatile unsigned char vGu8UpdateTimerFlag=0; volatile unsigned int vGu16UpdateTimerCnt=0; unsigned char Gu8RunStart=0; //應用程序的總啟動 unsigned char Gu8RunStep=0; //應用程序的總運行步驟。建議跟vGu8RunStart成雙成對出現 unsigned char Gu8RunStatus=0; //當前倒計時的狀態。0代表停止,1代表正在工作中 unsigned char Gu8EditData\_4=0; //對應顯示右起第4位數碼管的“位”數據,是中間變量。 unsigned char Gu8EditData\_3=0; //對應顯示右起第3位數碼管的“位”數據,是中間變量。 unsigned char Gu8EditData\_2=0; //對應顯示右起第2位數碼管的“位”數據,是中間變量。 unsigned char Gu8EditData\_1=0; //對應顯示右起第1位數碼管的“位”數據,是中間變量。 unsigned char Gu8Wd=1; //窗口選擇變量。人機交互程序框架的支點。初始化開機后顯示第1個窗口。 unsigned char Gu8WdUpdate=1; //整屏更新變量。初始化為1開機后整屏更新一次顯示。 unsigned char Gu8Part=0; //局部選擇變量。0代表當前窗口下沒有數據被選中。 unsigned char Gu8PartUpdate\_1=0; //局部1的更新變量, unsigned char Gu8PartUpdate\_2=0; //局部2的更新變量 unsigned char Gu8PartUpdate\_3=0; //局部3的更新變量, unsigned char Gu8PartUpdate\_4=0; //局部4的更新變量 volatile unsigned char vGu8Display\_Righ\_4=1; //顯示“1”,跟vGu32CountdownTimerCnt高位一致 volatile unsigned char vGu8Display\_Righ\_3=0; volatile unsigned char vGu8Display\_Righ\_2=0; volatile unsigned char vGu8Display\_Righ\_1=0; volatile unsigned char vGu8Display\_Righ\_Dot\_4=0; volatile unsigned char vGu8Display\_Righ\_Dot\_3=1; //開機默認保留顯示2個小數點 volatile unsigned char vGu8Display\_Righ\_Dot\_2=0; volatile unsigned char vGu8Display\_Righ\_Dot\_1=0; volatile unsigned char vGu8KeySec=0; void main() { SystemInitial(); Delay(10000); PeripheralInitial(); while(1) { KeyTask(); //按鍵的任務函數 DisplayTask(); //數碼管顯示的上層任務函數 RunTask(); //倒計時的應用程序 } } void PartUpdate(unsigned char u8Part) //局部選擇對應的某個局部變量更新顯示輸出 { switch(u8Part) { case 1: Gu8PartUpdate\_1=1; break; case 2: Gu8PartUpdate\_2=1; break; case 3: Gu8PartUpdate\_3=1; break; case 4: Gu8PartUpdate\_4=1; break; } } void RunTask(void) //倒計時的應用程序 { if(0==Gu8RunStart) { return; // 如果總開關處于停止狀態,則直接退出當前函數,不執行該函數以下的其它代碼 } switch(Gu8RunStep) { case 0: //在這個步驟里,主要用來初始化一些參數 vGu8UpdateTimerFlag=0; vGu16UpdateTimerCnt=10; //每10ms更新顯示一次當前倒計時的時間 vGu8UpdateTimerFlag=1; Gu8RunStep=1; //跳轉到每10ms更新顯示一次的步驟里 break; case 1: //每10ms更新一次顯示,確保實時顯示當前倒計時的時間 if(0==vGu16UpdateTimerCnt) //每10ms更新顯示一次當前倒計時的時間 { vGu8UpdateTimerFlag=0; vGu16UpdateTimerCnt=10; //重置定時器,為下一個10ms更新做準備 vGu8UpdateTimerFlag=1; Gu8WdUpdate=1; //整屏更新一次顯示當前倒計時的時間 if(0==vGu32CountdownTimerCnt) //如果倒計時的時間到,則跳轉到結束的步驟 { Gu8RunStep=2; //跳轉到倒計時結束的步驟 } } break; case 2: //倒計時結束的步驟 //Gu8RunStatus=0; //這行代碼注釋掉,讓每次新啟動之前都必須按一次K1復位按鍵才有效 Gu8RunStart=0; //倒計時的運行步驟的停止 Gu8RunStep=0; //總運行步驟歸零。建議跟vGu8RunStart成雙成對出現 vGu8BeepTimerFlag=0; vGu16BeepTimerCnt=VOICE\_TIME; //蜂鳴器發出“滴”一聲 vGu8BeepTimerFlag=1; Gu8WdUpdate=1; //整屏更新一次顯示當前倒計時的時間 break; } } void KeyTask(void) //按鍵的任務函數 { if(0==vGu8KeySec) { return; } if(0!=Gu8RunStatus) //在“非停止”狀態下,用return來攔截一些“不該響應”的按鍵 { if(2==vGu8KeySec) //在“非停止”狀態下,只響應\[復位\]這個按鍵 { ; //這里沒有return語句,表示可以繼續往下掃描本函數余下的代碼,沒有被攔截。 } else { return; //其余的按鍵則攔截退出 } } switch(vGu8KeySec) { case 1: //按鍵K1的“短按”。切換數碼管閃爍的位。 switch(Gu8Wd) //在某個窗口下 { case 1: //在窗口1下 if(0!=Gu8Part) //處于“閃爍模式”的時候,是“切換局部” { PartUpdate(Gu8Part); //切換之前的局部進行更新。 Gu8Part++; //切換局部 if(Gu8Part>4) { Gu8Part=1; } PartUpdate(Gu8Part); //切換之后的局部進行更新。 vGu8BeepTimerFlag=0; vGu16BeepTimerCnt=VOICE\_TIME; //蜂鳴器發出“滴”一聲 vGu8BeepTimerFlag=1; } break; } vGu8KeySec=0; break; case 2: //按鍵K2[加鍵]與[復位健] if(0!=Gu8Part) //處于“閃爍模式”的時候,是[加鍵] { switch(Gu8Wd) //在某個窗口下 { case 1: //在窗口1下 switch(Gu8Part) //二級支點的局部選擇 { case 1: //局部1被選中,代表右起第4位數碼管被選中。 if(Gu8EditData\_4<9) { Gu8EditData\_4++; //編輯“千位”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; case 2: //局部2被選中,代表右起第3位數碼管被選中。 if(Gu8EditData\_3<9) { Gu8EditData\_3++; //編輯“百位”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; case 3: //局部3被選中,代表右起第2位數碼管被選中。 if(Gu8EditData\_2<9) { Gu8EditData\_2++; //編輯“十位”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; case 4: //局部4被選中,代表右起第1位數碼管被選中。 if(Gu8EditData\_1<9) { Gu8EditData\_1++; //編輯“個位”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; } break; } } else //處于“沒有閃爍”的時候,是[復位健] { Gu8EditData\_4=Gu32SetData\_Countdown/10000%10; //分解成“十秒”個體 Gu8EditData\_3=Gu32SetData\_Countdown/1000%10; //分解成“個秒”個體 Gu8EditData\_2=Gu32SetData\_Countdown/100%10; //分解成“百毫秒”個體 Gu8EditData\_1=Gu32SetData\_Countdown/10%10; //分解成“十毫秒”個體 Gu8RunStatus=0; //倒計時返回停止的狀態 Gu8RunStart=0; //倒計時的運行步驟的停止 Gu8RunStep=0; //總運行步驟歸零。建議跟vGu8RunStart成雙成對出現 Gu8Wd=1; //返回設置數據的窗口 Gu8WdUpdate=1; //整屏更新一次顯示 } vGu8BeepTimerFlag=0; vGu16BeepTimerCnt=VOICE\_TIME; //蜂鳴器發出“滴”一聲 vGu8BeepTimerFlag=1; vGu8KeySec=0; break; case 3: //按鍵K3[減鍵]與[開始健] if(0!=Gu8Part) //處于“閃爍模式”的時候,是[減鍵] { switch(Gu8Wd) //在某個窗口下 { case 1: //在窗口1下 switch(Gu8Part) //二級支點的局部選擇 { case 1: //局部1被選中,代表右起第4位數碼管被選中。 if(Gu8EditData\_4>0) { Gu8EditData\_4--; //編輯“十秒”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; case 2: //局部2被選中,代表右起第3位數碼管被選中。 if(Gu8EditData\_3>0) { Gu8EditData\_3--; //編輯“個秒”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; case 3: //局部3被選中,代表右起第2位數碼管被選中。 if(Gu8EditData\_2>0) { Gu8EditData\_2--; //編輯“百毫秒”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; case 4: //局部4被選中,代表右起第1位數碼管被選中。 if(Gu8EditData\_1>0) { Gu8EditData\_1--; //編輯“十毫位”個體的中間變量 } PartUpdate(Gu8Part); //當前局部更新顯示輸出到數碼管 break; } break; } } else //處于“沒有閃爍”的時候,是[開始健] { if(0==Gu8RunStatus) //在停止狀態下 { vGu8CountdownTimerFlag=0; vGu32CountdownTimerCnt=Gu32SetData\_Countdown; //從“設置值”開始倒計時 vGu8CountdownTimerFlag=1; //允許倒計時的軟件定時器的啟動 Gu8RunStatus=1; //倒計時處于工作狀態(并且,這一瞬間才正式啟動倒計時) Gu8RunStart=1; //倒計時的運行步驟的總開關開啟 Gu8RunStep=0; //總運行步驟歸零。建議跟vGu8RunStart成雙成對出現 Gu8Wd=2; //進入倒計時運行的窗口 Gu8WdUpdate=1; //整屏更新一次顯示,確保在啟動的時候能顯示到最新的數據 } } vGu8BeepTimerFlag=0; vGu16BeepTimerCnt=VOICE\_TIME; //蜂鳴器發出“滴”一聲 vGu8BeepTimerFlag=1; vGu8KeySec=0; break; case 4: //K1按鍵的“長按”,具有進入和退出“閃爍模式”的功能。“退出”隱含“確定” switch(Gu8Wd) //在某個窗口下 { case 1: //在窗口1下 if(0==Gu8Part) //處于“沒有閃爍”的時候,將進入“閃爍模式” { Gu8EditData\_4=Gu32SetData\_Countdown/10000%10; //分解成“十秒”個體 Gu8EditData\_3=Gu32SetData\_Countdown/1000%10; //分解成“個秒”個體 Gu8EditData\_2=Gu32SetData\_Countdown/100%10; //分解成“百毫秒”個體 Gu8EditData\_1=Gu32SetData\_Countdown/10%10; //分解成“十毫秒”個體 Gu8Part=1; //進入“閃爍模式”,從“局部1”開始閃爍 } else //處于“閃爍模式”的時候,將退出到“沒有閃爍”,隱含“確定”功能 { //把個體合并還原成數據 Gu32SetData\_Countdown=Gu8EditData\_4\*10000+Gu8EditData\_3\*1000; Gu32SetData\_Countdown=Gu32SetData\_Countdown+Gu8EditData\_2\*100; Gu32SetData\_Countdown=Gu32SetData\_Countdown+Gu8EditData\_1\*10; Gu8Part=0; //退出“閃爍模式” Gu8WdUpdate=1; //整屏更新 } break; } vGu8BeepTimerFlag=0; vGu16BeepTimerCnt=VOICE\_TIME; //蜂鳴器發出“滴”一聲 vGu8BeepTimerFlag=1; vGu8KeySec=0; break; } } void DisplayTask(void) //數碼管顯示的上層任務函數 { switch(Gu8Wd) //以窗口選擇Gu8Wd為支點,去執行對應的窗口顯示函數。又一次用到switch語句 { case 1: Wd1(); //窗口1顯示函數。用來設置參數。 break; case 2: Wd2(); //窗口2顯示函數。倒計時的運行顯示窗口。 break; } } void Wd1(void) //窗口1顯示函數。用來設置參數。 { //需要借用的中間變量,用來拆分數據位。 static unsigned char Su8Temp\_4,Su8Temp\_3,Su8Temp\_2,Su8Temp\_1; //需要借用的中間變量 static unsigned char Su8BlinkFlag=0; //兩種狀態的切換判斷的中間變量 if(1==Gu8WdUpdate) //如果需要整屏更新 { Gu8WdUpdate=0; //及時清零,只更新一次顯示即可,避免一直進來更新顯示 //屬于靜態數據,起“裝飾”作用,切換窗口后只掃描一次的代碼。 vGu8Display\_Righ\_Dot\_4=0; vGu8Display\_Righ\_Dot\_3=1; //保留顯示2位小數點 vGu8Display\_Righ\_Dot\_2=0; vGu8Display\_Righ\_Dot\_1=0; Gu8PartUpdate\_1=1; //局部1更新顯示 Gu8PartUpdate\_2=1 ;//局部2更新顯示 Gu8PartUpdate\_3=1 ;//局部3更新顯示 Gu8PartUpdate\_4=1 ;//局部4更新顯示 } if(1==Gu8PartUpdate\_1) //局部1更新顯示 { Gu8PartUpdate\_1=0; //及時清零,只更新一次顯示即可,避免一直進來更新顯示 if(Gu32SetData\_Countdown<10000) { Su8Temp\_4=10; //顯示“無” } else { Su8Temp\_4=Gu8EditData\_4; //顯示“十秒”的臨時中間個體,屬于動態數據。 } vGu8Display\_Righ\_4=Su8Temp\_4; //過渡需要顯示的數據到底層驅動變量 } if(1==Gu8PartUpdate\_2) //局部2更新顯示 { Gu8PartUpdate\_2=0; //及時清零,只更新一次顯示即可,避免一直進來更新顯示 Su8Temp\_3=Gu8EditData\_3; //顯示“個秒”的臨時中間個體,屬于動態數據。 vGu8Display\_Righ\_3=Su8Temp\_3; //過渡需要顯示的數據到底層驅動變量 } if(1==Gu8PartUpdate\_3) //局部3更新顯示 { Gu8PartUpdate\_3=0; //及時清零,只更新一次顯示即可,避免一直進來更新顯示 Su8Temp\_2=Gu8EditData\_2; //顯示“百毫秒”的臨時中間個體,屬于動態數據。 vGu8Display\_Righ\_2=Su8Temp\_2; //過渡需要顯示的數據到底層驅動變量 } if(1==Gu8PartUpdate\_4) //局部4更新顯示 { Gu8PartUpdate\_4=0; //及時清零,只更新一次顯示即可,避免一直進來更新顯示 Su8Temp\_1=Gu8EditData\_1; //顯示“十毫秒”的臨時中間個體,屬于動態數據。 vGu8Display\_Righ\_1=Su8Temp\_1; //過渡需要顯示的數據到底層驅動變量 } if(0==vGu16BlinkTimerCnt) //某位被選中的數碼管跳動閃爍的定時器 { vGu8BlinkTimerFlag=0; vGu16BlinkTimerCnt=BLINK\_TIME; //重設定時器的定時時間 vGu8BlinkTimerFlag=1; switch(Gu8Part) //某個局部被選中,則閃爍跳動 { case 1: if(0==Su8BlinkFlag) //兩種狀態的切換判斷 { Su8BlinkFlag=1; Su8Temp\_4=10; //右起第4個顯示“不顯示”(10代表不顯示) } else { Su8BlinkFlag=0; Su8Temp\_4=Gu8EditData\_4; //顯示“十秒”的臨時中間個體,屬于動態數據。 } break; case 2: if(0==Su8BlinkFlag) //兩種狀態的切換判斷 { Su8BlinkFlag=1; Su8Temp\_3=10; //右起第3個顯示“不顯示”(10代表不顯示) } else { Su8BlinkFlag=0; Su8Temp\_3=Gu8EditData\_3; //顯示“個秒”的臨時中間個體,屬于動態數據。 } break; case 3: if(0==Su8BlinkFlag) //兩種狀態的切換判斷 { Su8BlinkFlag=1; Su8Temp\_2=10; //右起第2個顯示“不顯示”(10代表不顯示) } else { Su8BlinkFlag=0; Su8Temp\_2=Gu8EditData\_2; //顯示“百毫秒”的臨時中間個體,屬于動態數據。 } break; case 4: if(0==Su8BlinkFlag) //兩種狀態的切換判斷 { Su8BlinkFlag=1; Su8Temp\_1=10; //右起第1個顯示“不顯示”(10代表不顯示) } else { Su8BlinkFlag=0; Su8Temp\_1=Gu8EditData\_1; //顯示“十毫秒”的臨時中間個體,屬于動態數據。 } break; default: //都沒有被選中的時候 if(Gu32SetData\_Countdown<10000) { Su8Temp\_4=10; //顯示“無” } else { Su8Temp\_4=Gu8EditData\_4; //顯示“十秒”的臨時中間個體,屬于動態數據。 } Su8Temp\_3=Gu8EditData\_3; //顯示“個秒”的臨時中間個體,屬于動態數據。 Su8Temp\_2=Gu8EditData\_2; //顯示“百毫秒”的臨時中間個體,屬于動態數據。 Su8Temp\_1=Gu8EditData\_1; //顯示“十毫秒”的臨時中間個體,屬于動態數據。 break; } vGu8Display\_Righ\_4=Su8Temp\_4; //過渡需要顯示的數據到底層驅動變量 vGu8Display\_Righ\_3=Su8Temp\_3; //過渡需要顯示的數據到底層驅動變量 vGu8Display\_Righ\_2=Su8Temp\_2; //過渡需要顯示的數據到底層驅動變量 vGu8Display\_Righ\_1=Su8Temp\_1; //過渡需要顯示的數據到底層驅動變量 } } void Wd2(void) //窗口2顯示函數。倒計時的運行顯示窗口。 { //需要借用的中間變量,用來拆分數據位。 static unsigned char Su8Temp\_4,Su8Temp\_3,Su8Temp\_2,Su8Temp\_1; //需要借用的中間變量 if(1==Gu8WdUpdate) //如果需要整屏更新 { Gu8WdUpdate=0; //及時清零,只更新一次顯示即可,避免一直進來更新顯示 //先分解數據,注意,這里分解的時候,“先整除后求余”必須用一行代碼一氣呵成,不能拆 //分成兩行代碼,否則會有隱患會有bug。除非,把四個臨時變都改成unsigned long類型。 //Su8Temp\_4提取“十秒”位。 Su8Temp\_4=vGu32CountdownTimerCnt/10000%10; //實際精度是0.001秒,但顯示精度是0.01秒 //Su8Temp\_3提取“個秒”位。 Su8Temp\_3=vGu32CountdownTimerCnt/1000%10; //實際精度是0.001秒,但顯示精度是0.01秒 //Su8Temp\_2提取“百毫秒”位。 Su8Temp\_2=vGu32CountdownTimerCnt/100%10; //實際精度是0.001秒,但顯示精度是0.01秒 //Su8Temp\_1提取“十毫秒”位。 Su8Temp\_1=vGu32CountdownTimerCnt/10%10; //實際精度是0.001秒,但顯示精度是0.01秒 //判斷數據范圍,來決定最高位數碼管是否需要顯示。 if(vGu32CountdownTimerCnt<10000) //10.000秒。實際4位數碼管最大只能顯示99.99秒 { Su8Temp\_4=10; //在數碼管轉換表里,10代表一個“不顯示”的數據 } //上面先分解數據之后,再過渡需要顯示的數據到底層驅動變量里,讓過渡的時間越短越好 vGu8Display\_Righ\_4=Su8Temp\_4; //過渡需要顯示的數據到底層驅動變量 vGu8Display\_Righ\_3=Su8Temp\_3; vGu8Display\_Righ\_2=Su8Temp\_2; vGu8Display\_Righ\_1=Su8Temp\_1; vGu8Display\_Righ\_Dot\_4=0; vGu8Display\_Righ\_Dot\_3=1; //保留顯示2位小數點 vGu8Display\_Righ\_Dot\_2=0; vGu8Display\_Righ\_Dot\_1=0; } } void KeyScan(void) //按鍵底層的驅動掃描函數,放在定時中斷函數里 { static unsigned char Su8KeyShortFlag=0; //按鍵“短按”觸發的標志 static unsigned char Su8KeyLock1; static unsigned int Su16KeyCnt1; static unsigned char Su8KeyLock2; static unsigned int Su16KeyCnt2; static unsigned char Su8KeyLock3; static unsigned int Su16KeyCnt3; //需要詳細分析以下這段“短按”與“長按”代碼的朋友,請參考第96節。 if(0!=KEY\_INPUT1) { Su8KeyLock1=0; Su16KeyCnt1=0; if(1==Su8KeyShortFlag) { Su8KeyShortFlag=0; vGu8KeySec=1; //觸發K1的“短按” } } else if(0==Su8KeyLock1) { Su16KeyCnt1++; if(Su16KeyCnt1>=KEY\_FILTER\_TIME) { Su8KeyShortFlag=1; } if(Su16KeyCnt1>=KEY\_LONG\_TIME) { Su8KeyLock1=1; Su8KeyShortFlag=0; vGu8KeySec=4; //觸發K1的“長按” } } if(0!=KEY\_INPUT2) { Su8KeyLock2=0; Su16KeyCnt2=0; } else if(0==Su8KeyLock2) { Su16KeyCnt2++; if(Su16KeyCnt2>=KEY\_FILTER\_TIME) { Su8KeyLock2=1; vGu8KeySec=2; } } if(0!=KEY\_INPUT3) { Su8KeyLock3=0; Su16KeyCnt3=0; } else if(0==Su8KeyLock3) { Su16KeyCnt3++; if(Su16KeyCnt3>=KEY\_FILTER\_TIME) { Su8KeyLock3=1; vGu8KeySec=3; } } } void DisplayScan(void) //數碼管底層的驅動掃描函數,放在定時中斷函數里 { static unsigned char Su8GetCode; static unsigned char Su8ScanStep=1; if(0==vGu16ScanTimerCnt) { P0=0x00; P1\_0=1; P1\_1=1; P1\_2=1; P1\_3=1; switch(Su8ScanStep) { case 1: Su8GetCode=Cu8DigTable\[vGu8Display\_Righ\_1\]; if(1==vGu8Display\_Righ\_Dot\_1) { Su8GetCode=Su8GetCode|0x80; } P0=Su8GetCode; P1\_0=0; P1\_1=1; P1\_2=1; P1\_3=1; break; case 2: Su8GetCode=Cu8DigTable\[vGu8Display\_Righ\_2\]; if(1==vGu8Display\_Righ\_Dot\_2) { Su8GetCode=Su8GetCode|0x80; } P0=Su8GetCode; P1\_0=1; P1\_1=0; P1\_2=1; P1\_3=1; break; case 3: Su8GetCode=Cu8DigTable\[vGu8Display\_Righ\_3\]; if(1==vGu8Display\_Righ\_Dot\_3) { Su8GetCode=Su8GetCode|0x80; } P0=Su8GetCode; P1\_0=1; P1\_1=1; P1\_2=0; P1\_3=1; break; case 4: Su8GetCode=Cu8DigTable\[vGu8Display\_Righ\_4\]; if(1==vGu8Display\_Righ\_Dot\_4) { Su8GetCode=Su8GetCode|0x80; } P0=Su8GetCode; P1\_0=1; P1\_1=1; P1\_2=1; P1\_3=0; break; } Su8ScanStep++; if(Su8ScanStep>4) { Su8ScanStep=1; } vGu8ScanTimerFlag=0; vGu16ScanTimerCnt=SCAN\_TIME; vGu8ScanTimerFlag=1; } } void VoiceScan(void) //蜂鳴器的驅動函數 { static unsigned char Su8Lock=0; if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0) { if(0==Su8Lock) { Su8Lock=1; BeepOpen(); } else { vGu16BeepTimerCnt--; if(0==vGu16BeepTimerCnt) { Su8Lock=0; BeepClose(); } } } } void BeepOpen(void) { P3\_4=0; } void BeepClose(void) { P3\_4=1; } void T0\_time() interrupt 1 { VoiceScan(); //蜂鳴器的驅動函數 KeyScan(); //按鍵底層的驅動掃描函數 DisplayScan(); //數碼管底層的驅動掃描函數 if(1==vGu8ScanTimerFlag&&vGu16ScanTimerCnt>0) { vGu16ScanTimerCnt--; //遞減式的軟件定時器 } if(1==vGu8BlinkTimerFlag&&vGu16BlinkTimerCnt>0) //數碼管閃爍跳動的定時器 { vGu16BlinkTimerCnt--; //遞減式的軟件定時器 } //每10ms就定時更新一次顯示的軟件定時器 if(1==vGu8UpdateTimerFlag&&vGu16UpdateTimerCnt>0) { vGu16UpdateTimerCnt--; //遞減式的軟件定時器 } //倒計時實際走的時間的軟件定時器,注意,這里還附加了啟動狀態的條件“&&1==Gu8RunStatus” if(1==vGu8CountdownTimerFlag&&vGu32CountdownTimerCnt>0&&1==Gu8RunStatus) { vGu32CountdownTimerCnt--; //遞減式的軟件定時器 } TH0=0xfd; //此參數可根據具體的時間來修改,盡量確保每定時中斷一次接近1ms TL0=0x40; //此參數可根據具體的時間來修改,盡量確保每定時中斷一次接近1ms } void SystemInitial(void) { P0=0x00; P1\_0=1; P1\_1=1; P1\_2=1; P1\_3=1; TMOD=0x01; TH0=0xfd; //此參數可根據具體的時間來修改,盡量確保每定時中斷一次接近1ms TL0=0x40; //此參數可根據具體的時間來修改,盡量確保每定時中斷一次接近1ms EA=1; ET0=1; TR0=1; //上電初始化開機顯示的窗口 Gu8EditData\_4=Gu32SetData\_Countdown/10000%10; //分解成“十秒”個體 Gu8EditData\_3=Gu32SetData\_Countdown/1000%10; //分解成“個秒”個體 Gu8EditData\_2=Gu32SetData\_Countdown/100%10; //分解成“百毫秒”個體 Gu8EditData\_1=Gu32SetData\_Countdown/10%10; //分解成“十毫秒”個體 Gu8Wd=1; //返回設置數據的窗口 Gu8WdUpdate=1; //整屏更新一次顯示 } void Delay(unsigned long u32DelayTime) { for(;u32DelayTime>0;u32DelayTime--); } void PeripheralInitial(void) { }
                  <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>

                              哎呀哎呀视频在线观看