1.定時器&蜂鳴器
一般定時器中斷函數(shù)里的內(nèi)容最好是能夠快速地去執(zhí)行完,比如只執(zhí)行幾條簡單的語句,這樣與主函數(shù)配合才會使程序更加高效。前期教學(xué)里,我們只使用定時器中斷負(fù)責(zé)某個IO引腳間隔跳變或者使一個變量間隔自加1的簡單語句。
比如我們現(xiàn)在要實現(xiàn)間隔50ms左右的時間讓流水燈左右循環(huán)移動的同時,還需要無源蜂鳴器一直響,這樣的功能,思路該怎么去思考?
首先我們知道無源蜂鳴器要想鳴叫的比較尖銳,那P1.6需要一個合適的脈沖信號,這個信號筆者打算使P1.6高低電平保持的時間為300微秒不斷循環(huán)。
所以我們用定時器中斷實現(xiàn)P1.6的電平間隔跳變,主函數(shù)里負(fù)責(zé)完成流水燈的任務(wù)即可。
2.代碼
#include <reg52.h> #include <function.h>//詳見第六章第8講 u8 T0RH, T0RL; void TIM0_Init(u32 us,int trim)//trim:微調(diào) { u32 tmp; //臨時變量 tmp = 11059200 / 12; //定時器計數(shù)頻率 tmp = ( tmp * (us/100) )/10000;//計算所需的計數(shù)值 tmp = 65536 - tmp; //計算定時器重載值 tmp = tmp+trim; //補(bǔ)償中斷響應(yīng)延時造成的誤差 T0RH = (unsigned char)(tmp>>8);//定時器重載值拆分為高低字節(jié) T0RL = (unsigned char)tmp; TMOD &= 0xF0; //清0低四位 TMOD |= 0x01; //設(shè)置定時器0為工作模式1 TH0 = T0RH; //加載T0重載值 TL0 = T0RL; ET0 = 1; //閉合定時器0中斷的開關(guān) TR0 = 1; //啟動定時器0 } void main() { u8 i,dir; LED_Init(); //初始化LED硬件模塊 EA = 1; //閉合總中斷開關(guān) TIM0_Init(300,0); //用定時器0定時300us,不微調(diào) while(1) { if(i<8)dir=0;//向左移 if(dir==0)P0=~(0x01<<i); if(i>=8)dir=1;//向右移 if(dir==1)P0=~( 0x80>>(i-7) );//當(dāng)i大于等于8之后,(i-7)其實也還是在1~7之間變化 i++; if(i>=15)i=1;//讓i一直在1~14之間變化 delay_ms(50); } } void TIM0_IRQHandler() interrupt 1 { TH0 = T0RH; //重新加載重載值 TL0 = T0RL; BEEP=!BEEP; }
可以看到使用定時器中斷比外部中斷觸發(fā)還要高效。
3.講解微調(diào)
然后回到上一講說過的怎么測試然后去微調(diào)使定時時間更精確。
拿我們這講的代碼來說,首先在不微調(diào)的情況下,也就是傳入的參數(shù)trim為0,看看定時的時間是多少。
進(jìn)入軟件調(diào)試模式,在“BEEP=! BEEP;”設(shè)置斷點,在沒有微調(diào)之前觀察每次執(zhí)行“BEEP =! BEEP;”的間隔時間。
按下RST復(fù)位之后,先按兩次RUN
再按一次RUN
定時時間為0.003285-0.002979= 0.000306s
所以定時時間超了6微秒,則需要給trim一個合適的參數(shù),這里筆者調(diào)出了最合適的數(shù)為6,所以我們初始化定時器時改為
TIM0_Init(300,6); //用定時器0定時300us,6是微調(diào)使定時時間更精確
這樣每次跳轉(zhuǎn)到中斷函數(shù)去執(zhí)行的間隔時間就為精確的300us了。
當(dāng)我們要定時十毫秒或者二三十毫秒時,微調(diào)的數(shù)可能就不是6了,而是20之間或者其他數(shù),所以每次想要精確定時就需要軟件調(diào)試親自測試。
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:
一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程