1.實用性改善
為了使上一講的功能更加完善,我們編寫新的實用型的代碼,效果是讓數(shù)碼管顯示的數(shù)就是輸入引腳高電平持續(xù)的微秒數(shù),最高能捕獲到999999微秒。如果高電平持續(xù)的時間超出這個取值范圍,那么數(shù)碼管不夠顯示,所以超出范圍的話我們就讓6個數(shù)碼管顯示 FFFFFF。
因為計數(shù)器計時到65535之后就會產(chǎn)生溢出,也就是超過71ms就會溢出一次,我們知道計數(shù)器溢出也是會產(chǎn)生中斷的,所以在中斷函數(shù)里我們實現(xiàn)讓變量x簡單的自加1表明時間過去了71毫秒左右。
假設(shè)高電平持續(xù)的時間有75毫秒左右,那么得出最后的微秒數(shù)就是
x*71111+(TH0*256+TL0)*(12/11059200)*1000000;
現(xiàn)在我們首次使用float類型的變量,第一次使用帶小數(shù)點的數(shù)據(jù)類型。
不同的數(shù)據(jù)類型之間運算要進行強制轉(zhuǎn)換,請參考《手把手教你學51單片機》文檔10.1.1節(jié)。
我們定義的float類型變量capture_val就是用來記錄持續(xù)高電平的微秒數(shù)。請看以下三段代碼
capture_val=(float)TH0*256.0+(float)TL0; capture_val=(capture_val*12.0)/11.0592; capture_val=x*71111.0+capture_val;
第一段是取出計數(shù)器的值。第二段就是把計數(shù)器的值乘以(12/11059200),意思是得到的秒數(shù),但是我們需要的是微秒數(shù),所以除以11.0592就是把秒數(shù)放大了10的6次方倍。第三段代碼則是,溢出過好幾次71.111ms,所以需要加上這些時間。
我們記住,浮點型的數(shù)據(jù)加減乘除其他數(shù)時我們要加小數(shù)點。
還有函數(shù)參數(shù)的傳遞也要強制轉(zhuǎn)換,比如“ShowNumber((u32)capture_val);”
capture_val本身是float類型,想顯示正整數(shù)就要強制轉(zhuǎn)換為unsigned long類型。
2.代碼
#include <reg52.h> #include <function.h> //詳見第六章第8講 float x=0; //請用杜邦線把P1.6和P3.2連接起來 void main() { u8 i; float capture_val; LED_Init(); //初始化LED硬件模塊 TMOD=0x09; //低四位 1001 EA=1; //閉合總中斷開關(guān) ET0=1; BEEP=0; //先讓P1.6輸出低電平 TR0=1; BEEP=1; //開始計數(shù) delay_ms(500); //軟件仿真調(diào)試出此處的延時時間為698275.8微秒 BEEP=0; //停止計數(shù) capture_val=(float)TH0*256.0+(float)TL0; capture_val=(capture_val*12.0)/11.0592; capture_val=x*71111.0+capture_val; if(capture_val>999999.0) { for(i=0;i<6;i++)LedBuff[i]=LedChar[15]; //超出數(shù)碼管的顯示范圍就顯示FFFFFF } else ShowNumber((u32)capture_val); //顯示沒超過999999時的數(shù) while(1) { SEG_Scan(); } } void TIM0_IRQHandler() interrupt 1 { x=x+1.0; }
我們把“delay_ms(500);”改為“delay_ms(100);”,然后先軟件仿真調(diào)試看看“delay_ms(100);”花費了多少時間,接著再下載進開發(fā)板看看數(shù)碼管顯示的數(shù)值是多少,記住要保證P3.2和P1.6用杜邦線相連。
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習題和答疑,點擊了解:
一點編程也不會寫的:零基礎(chǔ)C語言學練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學奧賽或C++選手的 必學C++課程
藍橋杯ACM、信息學奧賽的必學課程:算法競賽課入門課程
手把手講解近五年真題的藍橋杯輔導課程