我剛剛看了一些關于單片機的知識,第一個就是關于led燈閃爍的,led燈的發(fā)光原理就是加電壓,它有一個限流電阻,一個二極管,接地。不同的板子led之間的不同就是改變家的電壓還是改變接地。我使用的led燈改變的是接地,即板子上已經(jīng)給了電壓,而我則可以改變接地電壓,所以如果我給接地電壓高的話,二極管就不會亮,我給低,二極管就亮。
而要想實現(xiàn)閃爍,那就是不斷的給led的接地口賦高電平,低電平,這樣不斷循環(huán),就實現(xiàn)了閃爍。
現(xiàn)在的關鍵就是停頓時間的實現(xiàn),比如我想實現(xiàn)1s內的閃爍,就是有0.5s亮,有0.5s滅。這時就要延時函數(shù)了,因為你一閃一滅是很快的,必須加延時才能,實現(xiàn)這種功能。
延時函數(shù)可以分為好幾類,比如你自己寫個延時函數(shù)如
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i
{
for(j=0;j<500;j++) //內嵌循環(huán)的空指令數(shù)量
{
; //一個分號相當于執(zhí)行一條空語句
}
}
}
這就是一個延時函數(shù),然后在主程序中你運行這個函數(shù),就會延時了。看起來好像很不錯的實現(xiàn)了目標。可是這樣會有一個后果,在執(zhí)行延時函數(shù)的過程中,別的任務就不能處理了,就只能完成這一個任務,這當然就不好了。
下面就有了另外一種方法,這種方法是利用主程序中的循環(huán)次數(shù)來實現(xiàn)延時。原理很簡單,因為單片機永遠是出于死循環(huán)中的,那你實現(xiàn)一個循環(huán)需要一定的時間吧,而且基本每次你實現(xiàn)循環(huán)的時間也差不了多少,那這樣我就可以利用了,我統(tǒng)計你運行的次數(shù),再乘上你每次運行的時間,這樣不就能得到一段時間了嗎?然后利用這段時間進行延時,不就能達到目標了嗎?這種方法的確很棒。
但真的完美嗎?不足的就是每次循環(huán)究竟需要多長時間,這個需要你不斷的估計,你只要往程序中加點內容,那循環(huán)時間就好變化,然后就要修改統(tǒng)計次數(shù),這個過程需要一遍一遍的做,效率不高,很煩,對于后期很不好。
人總是最求完美的,雖然永遠做不到。下面就有人有了更好的方法了,非常完美。
這個方法跟上面的原理有點類似,也是通過知道運行時間,然后通過統(tǒng)計運行次數(shù)來得到一段時間用于循環(huán)。想想單片機中有一個部分它的運行時間是固定的,想到了嗎?沒錯,定時器啊!
我們可以通過設置定時器來設定我們所說的運行時間,而且比較不錯。TMOD的工作方式設為0X01,就是定時器1模式下的工作方式1。然后高八位TH0=0xf8,低八位TL0=0x2f,其實就是計數(shù)值為2000,65535-2000=63535,63535的十六進制值就是f82f。這樣利用上面的原理,定時器每隔一段時間就會產(chǎn)生中斷,然后在服務程序中設置一個變量,每次中斷都自加一次,當達到我們設定的值時,就實現(xiàn)燈亮還是燈滅,然后變量清0,再繼續(xù)下去,就能實現(xiàn)led燈的閃爍了。
以上就是關于led燈閃爍的知識,硬件上原理很簡單,軟件上給出了三種方法實現(xiàn)閃爍。三種方法是不斷推進的,原理或相同或不同,我是有所悟了。
原理抽象為主動實現(xiàn),被動實現(xiàn)。后面兩個可以認為是接力打力,但第一種方法其實也是,cpu每運行一個指令是多長時間,然后我讓它運行多少次,這兩個相乘就得到我要的時間。而到了第二個時,也是每次運行時間相乘運行次數(shù)得到我要的時間,只是這次它的每次運行時間沒有刻意去得到,而是利用了程序中的死循環(huán)。到了第三個,也是這樣,每次運行時間利用了定時器,這樣更加精確了,這到和第一種方法有點像了,只是沒浪費cpu,看來不浪費cpu就是好方法了。本質上延時都是運行時間相乘運行次數(shù)。