前面一課掌握了嵌入式程序源代碼級調(diào)試,為復(fù)雜單片機實驗程序的調(diào)試做好了準備工作。本次實驗完成流水燈電路模型設(shè)計和編程,在實驗過程中,學習流水燈電路設(shè)計、編寫延遲函數(shù)、循環(huán)移位宏定義。
流水燈電路設(shè)計
本次實驗設(shè)計要求通過單片機P0口實現(xiàn)流水燈控制電路,P0口8個端口外接8個LED,每個LED串聯(lián)一個200歐姆的限流電阻,8個限流電阻的公共端接5V直流電源。電路設(shè)計如下圖所示:
8個LED正極端通過串聯(lián)電阻接5V直流電源,負極端接P0端口,只要給P0端口一個低電平,就可以點亮LED,若需要熄滅LED,需要給P0端口一個高電平,要實現(xiàn)LED流水燈功能,只要將8個LED依次點亮、熄滅即可。
編寫時間延遲函數(shù)
流水燈電路要求LED依次點亮,每個LED要持續(xù)亮一段時間后熄滅。用程序來控制LED的點亮和熄滅,只需要將與LED連接的端口寫入低電平或高電平即可,代碼如下:
#include
void main()
{
P0 = 0xFF;
P0 = 0xFD;
}
上述代碼第1條語句將P0第0位寫入低電平,與第0位連接的lED被點亮,第2條語句將第0位寫入高電平,與第0位連接的lED熄滅。兩條語句連續(xù)執(zhí)行,每條語句的執(zhí)行時間非常短,也就十幾微秒,LED點亮后很快被熄滅,人們通過眼睛感覺不到LED被點亮。因此需要在第1條語句和第2條語句之間進行時間延遲,延遲一段時間后再執(zhí)行第2條語句。
如何用軟件來模擬延時時間呢?在設(shè)計的電路模型中,51單片機的時鐘頻率是12MHZ,一個時鐘周期約0.08微秒,一個機器周期由12個時鐘周期構(gòu)成,一個機器周期約1微秒,51單片機執(zhí)行一個指令的時間是機器周期的倍數(shù),若使用for循環(huán)語句來實現(xiàn)時間延遲,一條基本的for循環(huán)語句執(zhí)行時間大約為8微秒,若延遲500毫秒,大約需要執(zhí)行500*120次循環(huán)。
// 時間延遲函數(shù)
void delay(unsigned int millisecond)
{
unsigned int i,j;
for(i=millisecond;i >0;i--)
for(j=120;j >0;j--);
}
delay()函數(shù)延遲millisecond毫秒,函數(shù)使用for嵌套循環(huán),外層for循環(huán)用于控制延遲的毫秒數(shù),內(nèi)層for循環(huán)用于控制1毫秒執(zhí)行的語句次數(shù)。
循環(huán)移位
流水燈需要在每個時間間隔內(nèi)只有一個LED點亮,其余LED均為熄滅狀態(tài),流水燈可以通過循環(huán)左移實現(xiàn)。循環(huán)左移是將操作數(shù)的二進制位按1位進行循環(huán)左移,移出的位并不會丟失,而是被后續(xù)移動的位填充。
P0默認值為0xFE,P0第0位的LED被點亮,其它位熄滅;延遲一段時間后,P0循環(huán)左移1位,其值為0xFD,P0第1位LED被點亮,其它位熄滅;延遲一段時間后,P0循環(huán)左移1位,其值為0xFB,P0第2位LED被點亮,其它位熄滅;以此類推,P0不斷循環(huán)左移1位,從而實現(xiàn)了流水燈控制。
C語言并沒有提供循環(huán)左移或循環(huán)右移的運算功能,需要開發(fā)者自己編程實現(xiàn)。
循環(huán)左移位的具體算法如上圖所示:value為操作數(shù),其值為0xFE,先將value左移1位,賦值給變量a,其值為0xFC,然后將value右移7位,賦值給變量b,其值為0X1,最后計算a|b,計算結(jié)果為value循環(huán)左移1位,并將計算結(jié)果賦值為value。
流水燈算法實現(xiàn)代碼如下:
void main()
{
unsigned char value=0xfe,a,b;
unsigned char count = 0;
while(1)
{
P0 = value;
delay(5000);
a = value < < 1;
b = value > > 7;
value = a | b;
count += 1;
if( count >= 8 )
{
value = 0xfe;
count = 0;
}
}
}
算法通過while循環(huán)實現(xiàn)流水燈控制,在循環(huán)內(nèi)部,變量value賦值給P0,點亮第0位的LED,其它位的LED為熄滅狀態(tài),然后調(diào)用delay()函數(shù)延遲5000毫秒,value循環(huán)左移1位,在下輪循環(huán)中,點亮第1位的LED,其它位的LED為熄滅狀態(tài),以此類推……。
count為計數(shù)變量,當流水燈循環(huán)點亮一次后,將value重新賦值為0xFE,并將conunt清零。
考慮到循環(huán)移位是經(jīng)常使用的操作,可以將循環(huán)左移位操作定義為宏,在代碼中直接調(diào)用宏就可以了。
循環(huán)左移位的宏定義:
#define ROTATE_LEFT(x) ((x) << 1) | ((x) >> 7 )
完整C程序代碼如下:
#include
#define ROTATE_LEFT(x) ((x) < < 1) | ((x) > > 7 )
void delay(unsigned int millisecond)
{
unsigned int i,j;
for(i=millisecond;i >0;i--)
for(j=120;j >0;j--);
}
void main()
{
unsigned char value=0xfe,count=0;
while(1)
{
P0 = value;
delay(5000);
value = ROTATE_LEFT(value);
count += 1;
if( count >= 8 )
{
value = 0xfe;
count = 0;
}
}
}
實驗小結(jié)
通過這次實驗,掌握了流水燈的電路模型設(shè)計和編程,流水燈電路模型比較簡單,單片機通過I/O口的8個端口來控制8個LED的點亮和熄滅。流水燈的控制通過編程實現(xiàn),編程主要涉及到時間延遲函數(shù)和循環(huán)左移位宏定義,時間延遲函數(shù)用于控制間LED點亮和熄滅的隔時間,循環(huán)左移位用于控制I/O口循環(huán)輸出高電平和低電平。
-
led
+關(guān)注
關(guān)注
240文章
23062瀏覽量
657046 -
單片機
+關(guān)注
關(guān)注
6030文章
44489瀏覽量
631968 -
嵌入式
+關(guān)注
關(guān)注
5059文章
18973瀏覽量
302016 -
電路設(shè)計
+關(guān)注
關(guān)注
6659文章
2420瀏覽量
202813 -
流水燈
+關(guān)注
關(guān)注
21文章
432瀏覽量
59598
發(fā)布評論請先 登錄
相關(guān)推薦
評論