1.定時(shí)器與延時(shí)的區(qū)別
大家可能會(huì)覺得我們用延時(shí)函數(shù)照樣可以實(shí)現(xiàn)上一講代碼的實(shí)驗(yàn)現(xiàn)象,但是定時(shí)器與延時(shí)的概念不同,延時(shí)函數(shù)需要占用CPU的使用權(quán),正在延時(shí)的時(shí)候其他任務(wù)沒有CPU的使用權(quán)就會(huì)拖慢執(zhí)行效率。
而定時(shí)器是不需要占用CPU的使用權(quán)的,它是獨(dú)立自己運(yùn)行的,就像我們?cè)诘谝恢v的時(shí)候提到調(diào)好5分鐘的鬧鐘,在這5分鐘里我們可以隨意執(zhí)行任務(wù),也可以什么事都不做,但是5分鐘過后鬧鐘響了就要執(zhí)行相關(guān)的任務(wù)了。
所以上一講的代碼的實(shí)現(xiàn)原理就是每隔51微秒,有個(gè)變量會(huì)自加1,過了1000個(gè)51微秒的時(shí)候LED的狀態(tài)才會(huì)改變,可以說CPU在51ms的時(shí)間里基本沒什么事做,只是在51微秒到了的時(shí)候做了“cnt++;”這樣簡(jiǎn)單的任務(wù),然后又空閑地等下一個(gè)51微秒的到來再執(zhí)行“cnt++;”。
2.定時(shí)器中斷函數(shù)
與外部中斷一樣,定時(shí)器中斷也有中斷函數(shù),同理,程序去執(zhí)行中斷函數(shù)就會(huì)把TF0的中斷標(biāo)志位自動(dòng)清0,所以只要我們用了定時(shí)器中斷函數(shù),那么TF0就可以不用再出現(xiàn)在程序書寫中了。
還記得外部中斷這個(gè)圖嗎
同樣定時(shí)器0的中斷函數(shù)使能如下
至于“interrupt”后面的數(shù)字為什么是1,請(qǐng)?jiān)倏次覀円郧敖o過大家的這個(gè)圖的中斷函數(shù)編號(hào)就明白了
這些編號(hào)是為了區(qū)分哪些硬件資源的相關(guān)中斷函數(shù),如果我們同時(shí)使用兩個(gè)定時(shí)器,那么只能用“interrupt 1”和“interrupt 3”來區(qū)分誰是誰的中斷函數(shù)了。
使用“TIM0_IRQHandler”作為函數(shù)名也是模仿STM32定時(shí)器中斷函數(shù)名的寫法。
如果我們使用的是工作模式1,每次觸發(fā)中斷函數(shù)的執(zhí)行內(nèi)容首先就是再次給TH0和TL0賦初值保證下次的定時(shí)時(shí)間還是一樣。
這里我們使用中斷函數(shù)的執(zhí)行方式來實(shí)現(xiàn)30ms的間隔流水燈,算出TH0和TL0合成的“16位的變量”要填充的值為37888=0x9400。
在中斷函數(shù)里也是可以定義局部變量的,當(dāng)然如果這個(gè)變量是用來輔助流水燈的,那么肯定是要定義成靜態(tài)變量的。
3.代碼
#include <reg52.h> #include <function.h>//詳見第六章第8講 void main() { LED_Init(); //初始化LED硬件模塊 EA = 1; //閉合總中斷開關(guān) TMOD = 0x01; //設(shè)置定時(shí)器0為工作模式1 TH0 = 0x94; //設(shè)置定時(shí)時(shí)間為30ms TL0 = 0x00; ET0 = 1; //閉合定時(shí)器0中斷的開關(guān) TR0 = 1; //啟動(dòng)定時(shí)器0 while(1); } void TIM0_IRQHandler() interrupt 1 { static u8 i; TH0 = 0x94; //重新設(shè)置定時(shí)時(shí)間為30ms TL0 = 0x00; P0=~(0x80>>i);//這一次讓流水燈向右移 i++; if(i>=8)i=0; }
覺得30ms的流速太快,想改為300ms的話,修改一下中斷函數(shù)即可,如下
void TIM0_IRQHandler() interrupt 1 { static u8 i,cnt; TH0 = 0x94; //重新設(shè)置定時(shí)時(shí)間為30ms TL0 = 0x00; cnt++; if(cnt>=10) { cnt=0; P0=~(0x80>>i);//這一次讓流水燈向右移 i++; if(i>=8)i=0; } }
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程
從零到寫出一個(gè)爬蟲的Python編程課程
只會(huì)語法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程