李 蔣
(江蘇聯合職業技術學院蘇州建設交通分院,江蘇 蘇州 215000)
LED燈作為新型綠色環保光源,因其節能環保、壽命長、經濟實惠等特點,在現代社會各個領域應用廣泛,其中LED流水燈由于其酷似流水般的顯示效果,在城市廣告、工控面板等諸多領域都有應用[1]。近年來LED流水燈在汽車工業領域應用尤為廣泛,主要有汽車前照燈、轉向信號指示燈、制動指示燈、后視鏡燈、儀表盤顯示燈、車內氛圍燈等場合。汽車LED流水燈不僅具備裝飾效果,還會承擔一些功能性作用,比如汽車后視鏡、前照燈、尾燈上的流水燈就具有轉向信號指示功能。
LED流水燈要想實現燈光顯示的流水效果,需要專門的控制系統,目前比較常見的主要有兩種方案,一種是采用數字集成電路(移位寄存器、十進制計數/譯碼器等)[2-3],另外一種是采用單片機[4-5]。相對于數字集成電路,單片機具有體積小、功能強、成本低、控制電路外圍元件較少、控制程序相對簡單、制作難度低等顯著優點,在實現LED燈流水顯示效果方面具有明顯的優越性。
本文采用STC(宏晶)公司的8位51單片機STC89C52RC為主控芯片,首先進行51單片機最小系統及8位LED硬件電路設計,然后利用Keil uVision5集成開發軟件進行C語言軟件編程設計,分別通過位輸出操作、移位操作及循環移位操作3種控制方案進行8位LED汽車流水燈顯示功能設計和仿真調試。
流水燈顯示是指將多個LED燈組成的燈串按順序依次點亮,反復循環。本設計的首要目標是控制8個LED燈珠(按順序分別為D1、D2、D3、D4、D5、D6、D7、D8),模擬汽車流水燈的顯示效果,根據人眼的視覺暫留特性設定燈珠點亮時間間隔為200ms,按照D1~D8的順序逐次亮滅,產生流水顯示的效果,其工作過程如圖1所示。基于上述基礎設計,就能進一步實現正反向流水顯示、箭頭流水轉向顯示、菱形流水顯示、魚骨流水顯示等功能。

圖1 LED流水燈工作過程
其次,為了防止在開機或工作中因干擾而使程序失控,或工作中程序運行陷入某種死循環狀態等,系統需要具備復位的功能。另外,為了方便設計程序的調試驗證,需要能夠下載目標程序到單片機中,即系統還應具備通過串口進行燒錄的功能。
本設計采用的STC89C 52RC是宏晶公司的增強型MCS-51單片機,是一種低功耗、高性能的8位微控制器,具有8K在系統可編程Flash存儲器,可為眾多嵌入式控制應用系統提供高靈活、超有效的解決方案。STC89C52RC的主要特性如表1所示,引腳如圖2b所示。

表1 STC89C52RC單片機的主要特性
單片機若要正常工作,首先必須要具備一個最簡單的系統組成,即單片機最小系統。對于51單片機,最小系統主要包括電源電路、時鐘電路、復位電路及燒錄電路等部分。為了簡化系統設計,減少系統開發工作量,由前述總體設計目標,本設計需要實現8個LED燈流水顯示效果,因此本設計的硬件電路主要包括兩個部分:單片機最小系統和8位LED電路。
本設計基于STC89C52RC的單片機最小系統包括USB供電電路、時鐘電路、復位電路及串口燒錄電路,如圖2所示。

圖2 基于STC89C52RC的單片機最小系統
2.1.1 USB供電電路
作為電子元器件,單片機也是需要供電的。而單片機供電有一個技術范圍,不同單片機的供電范圍不盡相同,需要查看相關的技術手冊才知道具體的供電范圍。對于STC89C52RC單片機,需要使用5V電源,本設計通過USB接口來獲取5V電源,同時采用一片電源穩壓芯片AMS1117,可輸出穩定的3.3V直流電壓,為其它需要3.3V的外圍器件供電,具體如圖2a所示。需要注意的是,單片機承載不了過高的電壓,千萬不可以把單片機接到超標的電源電壓上,同時單片機正負極也要正確接上,否則容易燒壞單片機,嚴重的甚至可能發生爆炸。
2.1.2 時鐘電路
時鐘電路主要是產生單片機所必須的時鐘頻率,提供單片機工作時的時間基準,單片機的一切指令的執行都是建立在這個基礎上的。單片機的時鐘電路可以使用有源晶振或無源晶振。晶振是一種高精度、高穩定度的石英晶體振蕩器,可產生頻率穩定且峰值穩定的正弦波。本設計的時鐘電路采用的是11.0592MHz的無源晶振,能夠滿足STC89C52RC單片機的工作要求。STC89C52RC單片機的時鐘輸入引腳是18號引腳XTAL2和19號引腳XTAL1,需要兩個20pF的電容和一個11.0592MHz晶振作為外圍器件,具體如圖2b所示。
2.1.3 復位電路
當單片機工作過程中程序失控或者運行陷入死循環等故障狀態時,需要復位電路來讓整個電路恢復初始狀態。復位電路啟動的手段主要有:一是上電復位,即在給電路通電時立即進行復位操作;二是在必要時可以由按鍵手動操作復位;三是根據程序或者電路運行的需要自動進行復位。復位電路的原理一般是利用電容電壓不能突變的原理,將電容與電阻串聯,上電時刻,電容沒有充電,兩端電壓為0,此時提供復位脈沖,電源不斷地給電容充電,直至電容兩端電壓為電源電壓,電路進入正常工作狀態。復位電路一般比較簡單,大都是只用電阻和電容組合就可以實現,再復雜點就利用三極管等配合程序來實現。本設計電路采用按鍵復位,將一個10pF電容與一個10kΩ電阻串聯,復位按鍵并聯在電容兩端,一端接于電源VCC上,具體如圖2b所示。
2.1.4 串口燒錄電路
燒錄電路用于將計算機開發的軟件程序傳輸至單片機,實現計算機和單片機的通信。單片機燒錄電路通常采用典型的RS232串行接口,本設計是采用USB接口進行供電和燒錄程序的,因此燒錄電路采用了一片USB轉串口的轉接芯片CH340G,同時采用了一個12MHz的晶振和一些電阻、電容、穩壓二極管等外圍電子元器件,具體如圖2c所示。其中,CH340G的第5號引腳UD+與USB接口的D+端連接,CH340G的第6號引腳UD-與USB接口的D-端連接;CH340G的第2號引腳,即串口發射端TXD與STC89C52RC的P3.0口,即串口接收端RXD連接,CH340G的第3號引腳,即串口接收端RXD與STC89C52RC的P3.1口,即串口發射端TXD連接。
STC89C52RC單片機擁有4個8位并行的I/O端口:P0、P1、P2、P3口,共32個引腳。本設計采用獨立連接方式來控制LED燈,即每一個LED燈采用一個獨立的物理接口來控制。根據總體設計目標,需要控制8個LED燈工作,因此本設計采用了STC89C52RC單片機的P1.0~P1.7端口,具體電路如圖3所示。由圖3可見,8個LED為共陽極連接,每個LED陽極串聯一個限流電阻接于電源VCC上,若想使某一個LED燈亮,只需將它的陰極端變為低電平即可。例如,如果想點亮接在P1.0口的D1,那么只要使P1.0口的輸出電平變為低電平,LED的陽極電位大于陰極電位,二極管導通,LED發光。相反,如果想熄滅D1,就需要把P1.0口的輸出電平變為高電平,二極管截止。其他的7個LED燈的點亮和熄滅操作同理。

圖3 8位LED流水燈電路圖
Keil軟件是目前最流行的開發MCS-51系列單片機的軟件,它提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強大的仿真調試器等在內的完整開發方案,并通過一個集成開發環境(uVision)將這些部分組合在一起。本文利用Keil uVision5集成開發環境進行8位LED流水燈的C語言軟件編程設計,軟件主要分為兩個部分:延時控制部分和流水控制部分。
本設計的要求是8個LED燈輪流點亮,一個LED燈點亮、熄滅后,另一個LED燈再點亮、熄滅。由于人眼的視覺存在暫留效應,即人眼在觀察物體時,光信號傳入大腦神經,由于視神經的反應滯后,物體的影像會停留一段時間,在這段時間內即使物體消失,視覺中的影像也不會立即消失。而單片機執行語句的速度是非??斓?,在視覺暫留的影響下,程序執行時會使得我們從視覺上感覺所有LED燈均處于長亮狀態,無法看到輪流點亮的流水效果。因此,在軟件設計時必須要加入延時控制,以消除視覺暫留的影響。
單片機實現延時通常有兩種方法:一種是硬件延時,要用到定時器/計數器,這種方法可以提高CPU的工作效率,也能做到精確延時;另一種是軟件延時,這種方法主要采用循環體進行,程序實現方便。本設計選擇軟件延時,方法就是讓機器什么都不做,讓機器執行空指令,機器就會延時。具體做法就是首先將參數傳遞至for循環中,確定循環次數控制延時時間,在for循環體內再嵌套一個for循環以延長單個延時時間,通過設定總循環次數來控制延時時間,具體程序如下所示:
void delay(unsigned int xms)
{
unsigned int i,j;
for(i=xms;i>0;i--) //i=xms即延時約xms毫秒
for(j=112;j>0;j--);//嵌套循環
}
流水燈的控制方案有很多,其中比較典型的有位輸出操作、移位操作及循環移位操作3種控制方案,本設計分別采用這3種控制方案進行8位LED汽車流水燈仿真設計。
3.2.1 位輸出操作
位輸出操作是一種最直觀最易理解的方法,采用順序程序結構,用位指令控制P1口每一位輸出高低電平,從而控制相應的LED燈的點亮熄滅。位輸出操作的流程如圖4所示,具體的C程序如下所示:

圖4 位輸出操作流程圖
#include<reg52.h> //引用頭文件reg52.h
#define ON 0; //定義低電平時燈亮,0為低電平,ON為燈亮
#define OFF 1; //定義高電平時燈滅,1為高電平,OFF為燈滅
sbit LED0=P1^0; //將P1.0接口位定義為LED0,LED0連接第一個LED燈D1
sbit LED1=P1^1;
sbit LED2=P1^2;
sbit LED3=P1^3;
sbit LED4=P1^4;
sbit LED5=P1^5;
sbit LED6=P1^6;
sbit LED7=P1^7;
void main()
{
while(1) //加入死循環,讓8個LED燈輪流點亮后,繼續循環點亮
{
LED0=ON; //點亮第一個LED燈D1
delay(200); //延時200 ms
LED0=OFF; //熄滅第一個LED燈D1
LED1=ON;
delay(200);
LED1=OFF;
LED2=ON;
delay(200);
LED2=OFF;
LED3=ON;
delay(200);
LED3=OFF;
LED4=ON;
delay(200);
LED4=OFF;
LED5=ON;
delay(200);
LED5=OFF;
LED6=ON;
delay(200);
LED6=OFF;
LED7=ON;
delay(200);
LED7=OFF;
}
}
3.2.2 移位操作
在移位操作程序中,for語句的表達式用來描述循環的次數,即小燈的個數。在硬件電路中C51單片機的引腳輸出低電平時,燈亮;反之,燈熄。D1~D8循環亮的過程通過在for循環之中將對低點位進行移位指令來實現。移位操作流程見圖5。C程序如下:

圖5 移位操作流程圖
#include<reg52.h> //引用頭文件reg52.h
#define ON 0; //定義低電平時燈亮,0為低電平,ON為燈亮
#define OFF 1; //定義高電平時燈滅,1為高電平,OFF為燈滅
void main()
{
unsigned char i;
while(1)
{
P1=0xfe; //將P1寄存器的8位賦值為二進制數1111 1110,即點亮D1
for(i=0;i<8;i++)
{
delay(200); //延時200 ms
P1<<=1; //將P1左移一位
P1=P1|0X01; //將P1與二進制數0000 0001進行位或
}
}
}
3.2.3 循環移位操作
在上述位輸出操作程序中是逐個控制P1端口的每一位來實現的,而在移位操作程序中是先將P1寄存器左移一位再進行一次位或運算,因此程序都略顯復雜。循環移位操作是在程序一開始就給P1口送一個數,這個數讓P1.0為低電平,其他位為高電平,然后延時一段時間,再讓這個數據向高位移動,然后再輸出至P1口,這樣就實現“流水”效果。循環移位操作流程見圖6。具體C程序如下所示,程序中用到了intrins.h庫函數中的循環左移指令_crol_,程序結構簡單了很多。

圖6 循環移位操作流程圖
程序如下:
#include<reg52.h> //引用頭文件reg52.h
#include<intrins.h> //引用頭文件intrins.h
void main()
{
P1=0Xfe; //將P1寄存器的8位賦值為二進制數1111 1110
while(1)
{
delay(200); //延時200 ms
P1=_crol_(P1,1); //循環左移函數,將P1寄存器內的數向左移1位
}
}
應用Keil uVision5和STC-ISP軟件進行調試與驗證。啟動Keil開發環境,建立新工程liushuideng.uvproj,將文中流水燈控制程序輸入至主程序main.c中,調試程序,然后通過編譯生成為hex文件,再通過STC-ISP軟件將hex文件燒錄到設計電路板中(圖7)。燒錄完成后,電路板上電,8個LED燈即呈現流水的效果。通過驗證可見,文中所述位輸出、移位及循環移位3種流水燈操作控制程序均能實現汽車LED流水燈效果,但是觀察程序復雜程度,明顯第3種操作,即循環移位操作程序最為簡潔。需要注意的是,在使用STC-ISP燒錄軟件之前,需要安裝一個串口軟件,系統會分配一個串口號給電路板,STC-ISP軟件燒錄時需要正確配置。

圖7 STC-ISP燒錄軟件
本文以宏晶公司的51單片機STC89C52RC為主控芯片,設計了8位LED流水燈的硬件電路,以及位輸出、移位及循環移位3種操作的C軟件程序,通過Keil和STC-ISP軟件進行調試和驗證,達到了預期的設計目標。本設計的硬件電路和軟件程序完全可應用于汽車LED流水燈的實現,并且可以通過修改文中代碼,進一步拓展汽車流水燈應用?;谏鲜龌A設計和驗證,通過各種燈珠形狀排列,就能進一步實現正、反向流水顯示,箭頭流水轉向顯示,菱形流水顯示,魚骨流水顯示等功能,比如汽車花式流水燈、汽車燈光模式切換等。