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