有一天在網上看到一個製作——LED電子螢火蟲,我感覺電路很有特點,於是就想仿製一個。那個LED電子螢火蟲用的是ATtiny13單片機來控制,我也正好有。而且硬體製作比較簡單,成本也不高,10元錢都不到,就能DIY一個。雖然簡單,但是製作卻需要耐心和細心,畢竟需要連接12個LED,焊接的工作量不少,我自己用了一個下午才完成,而程序更是陸陸續續地寫了幾個小時。
估計你會很好奇地問,一共才6個可用I/O引腳的 ATtiny13,怎麼能驅動12個LED呢?其實,我要告訴你,它不僅可以點亮每個LED,而且還能控制每個LED的亮度呢!這才是本次製作的精華。在製作的過程中,發生了一點小小的意外。由於我購買的JST充電線和原來的充電器引腳相反,致使我原本打算使用的小型鋰電池損壞,不能充電。在萬般無奈的情況下,我只好更換體積更大的鋰電池了。
主要材料
這次的主要元器件就是ATtiny13單片機和12個LED。當然還有雙絞線、洞洞板、電池、空瓶子、電阻等其他輔助材料,如圖6.1所示。
本製作使用的是8個引腳的ATtiny13單片機,這款單片機現在的價格很便宜,4元左右就能買到。ATtiny13 是AVR 單片機,它有1KB 的 Flash、64B 的EEPROM、64B 的SRAM、6 個通用I/O口線、32個通用工作寄存器、1個具有比較模式的8位定時器/計數器、片內/外中斷、4路10位ADC、具有片內振蕩器的可編程看門狗定時器,以及3種可以通過軟體進行選擇的省電模式。12個LED為普通的3mm發黃色光的LED。
製作過程
1 焊接單片機插座。
2 焊接兩個電阻。
3 雙絞線套入熱縮管後,焊接LED。焊接好後,用打火機加熱熱縮管,使其收縮固定。最後,別忘了再扭下熱縮管。
4 焊接好的12個LED。
5 雙絞線焊接到洞洞板上。
6 洞洞板和雙絞線焊接好的效果。
7 焊接JST插頭、鋰電池和開關。
8 在瓶子上開口。
9 用熱熔膠固定。
10 裝入瓶子中。
控制原理
為什麼6個I/O能控制12個LED呢?它們之間會不會相互影響呢?其實,這樣的連接方式不僅能控制每個LED,還能控制其亮度呢!之所以能這樣連接,是因為AVR單片機的每個I/O都是3態輸出。如果用普通51單片機,這樣連接是不行的。
那麼又是如何控制LED的亮度呢?控制亮度的關鍵是ATtiny13的兩路PWM,它們可以分別設置連接到PB0和PB1引腳上。在ATtiny13使用內部振蕩器的情況下,PWM的最高頻率可設置為47.5kHz。而且PWM的極性可以通過設置寄存器而改變,這使得12個LED亮度的控制更加簡單了。
先談談如何控制每個LED單獨的亮和滅。ATtiny13的每個I/O都有4種狀態,即輸出0狀態、輸出1狀態、高阻態(懸空態)、帶上拉電阻的高阻態。要使LED亮,必須要讓LED中流過正向的電流,如果要讓最左邊的LED亮,PB1輸出1、PB2輸出0即可。但是,其他不相關的引腳需要設置成高阻態。否則,如果PB0此時也為1的話,第2個LED也會亮。總之,為了保證其他LED不受到影響,在設置某個燈亮時,必須先把所有I/O設置成不帶上拉的高阻態。
能控制亮和滅有什麼了不起?呵呵,其實還能控制每個LED單獨的漸變,就是漸漸變亮,漸漸變暗。我舉個例子吧,如果要最左邊的LED漸漸變亮,就先設置PB2引腳為0電平,PB1引腳設置為高電平驅動的PWM波。然後,程序逐漸控制PB1的PWM狀態,通過調整PWM高電平的脈寬長度來實現亮度控制。當PWM高電平的時間長時,LED就變亮了。反之,LED就變暗了。
那麼電路原理圖(見圖6.2)中第7個反過來接的LED怎麼實現亮度控制呢?原理還是一樣,只是PB2將剛才的0電平設置成1電平,原來PB1為高電平脈衝驅動的PWM波設置成低電平脈衝驅動的PWM波即可。同樣,要控制第7個LED的亮度,就控制PWM低電平的脈寬長度,當低電平的脈寬長度長時,LED就變亮了。反之,LED就變暗了。
那麼能實現所有的LED同時發光嗎?製作過程中,這個功能的實現倒是困擾了我一會兒。後來,我想到了動態掃描。什麼是動態掃描?老式電視機不就是這個原理嗎?電視機通過磁場讓射線高速地掃描屏幕,從而產生一幅畫面。那麼,讓每個燈分別亮1ms左右,然後像電視機一樣不斷地掃描,看上去就都亮了。在此基礎上,再控制每個燈的亮度數值,就能實現整體亮度控制了。如果LED足夠多,單片機引腳也足夠多,還可能顯示一副灰度畫面呢!
3種效果的程序編寫
程序的PWM頻率設置為最高的37.5kHz。之所以選擇這麼高的頻率是為了不影響動態掃描。試想,如果PWM頻率為100Hz,那麼還怎麼動態掃描呢?在程序中,動態掃描實際的頻率為62Hz。這已經足夠騙過人的眼睛,讓我們看不到燈的閃爍。
在單片機的中斷代碼中,程序每過26s就會產生溢出中斷一次,通過變量count計數中斷次數。當中斷的次數達到50次時,就更換下一個LED,顯示它對應的亮度。LED的亮度存儲到led[ ]這個數組中,每個LED通過載入對應的亮度值,即通過改變PWM產生寄存器的OCR0A與OCR0B,來實際控制高低電平脈寬長度,最終實現亮度的控制。當然,每次通過PWM控制亮度,都要先根據LED的驅動電平方式,重新設置PWM的控制模式。在此之前,還要記得設置不相關的引腳為高阻態。
LED的3種效果控制程序能夠實現LED不斷地變換,只要調用就能分別實現如下功能:所有LED的呼吸效果、逐個點亮和熄滅LED、LED流水顯示的效果。從編程的思路上講,led[ ]數組存放了12個元素,每個元素所存內容,即對應每個LED燈亮度值。要改變某個LED燈亮度,都是通過設置led[ ]數組中對應元素的 PWM 緩衝數值來實現自動變換。要讓所有的燈全亮只需設置數組中的每個元素的數值都為255即可。如果要一半的亮度就設置為128。要讓某個燈單獨最亮,只要設置這個LED元素數值為255,其他的元素為0。如果任意LED要產生漸漸變亮的效果,那麼只要對應數組元素中的數值從0逐漸變為255即可。同理,漸漸變暗,數值就從255變成0。要實現什麼樣的效果,大家可以通過改變led[ ]數組來實現。