第一種方法:
;這是一種比較笨但又最易理解的方法,采用順序程序結(jié)構(gòu),
;用位指令控制P0口的每一個位輸出高低電平,
;從而來控制相應(yīng)LED燈的亮滅 ;程序如下:
ORG 0000H ;單片機上電后從0000H地址執(zhí)行 AJMP START ;跳轉(zhuǎn)到主程序存放地址處 ORG 0030H ;設(shè)置主程序開始地址 START:MOV SP,#60H ;設(shè)置堆棧起始地址為60H clr P1.4 ;打開led使能,使得8個led燈可由P0口來控制 mov P2,#00110101B ;鎖存2個74hc573,防止數(shù)碼管點陣點亮. CLR P0.0 ;P0.0輸出低電平,使LED1點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.0 ;P0.0輸出高電平,使LED1熄滅 CLR P0.1 ;P0.1輸出低電平,使LED2點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.1 ;P0.1輸出高電平,使LED2熄滅 CLR P0.2 ;P0.2輸出低電平,使LED3點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.2 ;P0.2輸出高電平,使LED3熄滅 CLR P0.3 ;P0.3輸出低電平,使LED4點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.3 ;P0.3輸出高電平,使LED4熄滅 CLR P0.4 ;P0.4輸出低電平,使LED5點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.4 ;P0.4輸出高電平,使LED5熄滅 CLR P0.5 ;P0.5輸出低電平,使LED6點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.5 ;P0.5輸出高電平,使LED6熄滅 CLR P0.6 ;P0.6輸出低電平,使LED7點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.6 ;P0.6輸出高電平,使LED7熄滅 CLR P0.7 ;P0.7輸出低電平,使LED8點亮 ACALL DELAY ;調(diào)用延時子程序 SETB P0.7 ;P0.7輸出高電平,使LED8熄滅 ACALL DELAY ;調(diào)用延時子程序 AJMP START ;8個LED流了一遍后返回到標號START處再循環(huán) DELAY: ;延時子程序 MOV R0,#255 ;延時一段時間 D1: MOV R1,#255 DJNZ R1,$ DJNZ R0,D1 RET ;子程序返回 END ;程序結(jié)束 -------------------------------2循環(huán)移位法----------------------------------- /* 循環(huán)移位法: 在上個程序中我們是逐個控制P0端口的每個位來實現(xiàn)的,因此程序顯得有點復(fù)雜, 下面我們利用循環(huán)移位指令,采用循環(huán)程序結(jié)構(gòu)進行編程。我們在程序一開始就 給P0口送一個數(shù),這個數(shù)本身就讓P0.0先低,其他位為高,然后延時一段時間,再讓 這個數(shù)據(jù)向高位移動,然后再輸出至P0口,這樣就實現(xiàn)“流水”效果啦。由于8051 系列單片機的指令中只有對累加器ACC中數(shù)據(jù)左移或右移的指令,因此實際編程中 我們應(yīng)把需移動的數(shù)據(jù)先放到ACC中,讓其移動,然后將ACC移動后的數(shù)據(jù)再轉(zhuǎn)送到 P0口,這樣同樣可以實現(xiàn)“流水”效果。具體編程如下所示,程序結(jié)構(gòu)確實簡單了很多 */ ORG 0000H ;單片機上電后從0000H地址執(zhí)行 AJMP START ;跳轉(zhuǎn)到主程序存放地址處 ORG 0030H ;設(shè)置主程序開始地址 START:MOV SP,#60H ;設(shè)置堆棧起始地址為60H clr P1.4 ;打開led使能,使得8個led燈可由P0口來控制 mov P2,#00110101B ;鎖存2個74hc573,防止數(shù)碼管點陣點亮. MOV A,#0FEH ;ACC中先裝入LED1亮的數(shù)據(jù)(二進制的11111110) MOV P0,A ;將ACC的數(shù)據(jù)送P0口 MOV R0,#7 ;將數(shù)據(jù)再移動7次就完成一個8位流水過程 LOOP: RL A ;將ACC中的數(shù)據(jù)左移一位 MOV P0,A ;把ACC移動過的數(shù)據(jù)送p0口顯示 ACALL DELAY ;調(diào)用延時子程序 DJNZ R0,LOOP ;沒有移動夠7次繼續(xù)移動 AJMP START ;移動完7次后跳到開始重來,以達到循環(huán)流動效果 DELAY: ;延時子程序 MOV R0,#255 ;延時一段時間 D1: MOV R1,#255 DJNZ R1,$ DJNZ R0,D1 RET ;子程序返回 END ;程序結(jié)束 ----------------------------------3查表法--------------------------------------- /* 查表法: 上面的兩個程序都是比較簡單的流水燈程序,“流水”花樣只能實現(xiàn)單一 的“從左到右”流方式。運用查表法所編寫的流水燈程序,能夠?qū)崿F(xiàn)任意方式流水, 而且流水花樣無限,只要更改流水花樣數(shù)據(jù)表的流水數(shù)據(jù)就可以隨意添加或改變流 水花樣,真正實現(xiàn)隨心所欲的流水燈效果。我們首先把要顯示流水花樣的數(shù)據(jù)建在 一個以TAB為標號的數(shù)據(jù)表中,然后通過查表指令“MOVC A,@A+DPTR”把數(shù)據(jù)取到 累加器A中,然后再送到P0口進行顯示。具體源程序如下,TAB標號處的數(shù)據(jù)表可以根 據(jù)實現(xiàn)效果的要求任意修改。 */ ORG 0000H ;單片機上電后從0000H地址執(zhí)行 AJMP START ;跳轉(zhuǎn)到主程序存放地址處 ORG 0030H ;設(shè)置主程序開始地址 START:MOV SP,#60H ;設(shè)置堆棧起始地址為60H clr P1.4 ;打開led使能,使得8個led燈可由P0口來控制 mov P2,#00110101B ;鎖存2個74hc573,防止數(shù)碼管點陣點亮. MOV DPTR,# TAB ;流水花樣表首地址送DPTR LOOP: CLR A ;累加器清零 MOVC A,@A+DPTR ;取數(shù)據(jù)表中的值 CJNE A,#0FFH,SHOW ;檢查流水結(jié)束標志 AJMP START ;所有花樣流完,則從頭開始重復(fù)流 SHOW: MOV P0,A ;將數(shù)據(jù)送到P0口 ACALL DELAY ;調(diào)用延時子程序 INC DPTR ;取數(shù)據(jù)表指針指向下一數(shù)據(jù) AJMP LOOP ;繼續(xù)查表取數(shù)據(jù) DELAY: ;延時子程序 MOV R0,#255 ;延時一段時間 D1: MOV R1,#255 DJNZ R1,$ DJNZ R0,D1 RET ;子程序返回 TAB: ;下面是流水花樣數(shù)據(jù)表,用戶可據(jù)要求任意編寫 DB 11111110B ;二進制表示的流水花樣數(shù)據(jù),從低到高左移 DB 11111101B DB 11111011B DB 11110111B DB 11101111B DB 11011111B DB 10111111B DB 01111111B DB 01111111B ;二進制表示的流水花樣數(shù)據(jù),從高到低右移 DB 10111111B DB 11011111B DB 11101111B DB 11110111B DB 11111011B DB 11111101B DB 11111110B DB 0FEH,0FDH,0FBH,0F7H ;十六進制表示的流水花樣數(shù)據(jù) DB 0EFH,0DFH,0BFH,7FH DB 7FH,0BFH,0DFH,0EFH DB 0F7H,0FBH,0FDH,0FEH DB 0FFH ;流水花樣結(jié)束標志0FFH END ;程序結(jié)束
我放一個Keil C編的程序 ,請大家給點評
#include"AT89x51.h"
sbit LED=P1^4;
void main(void)
{
unsigned int a;
LED=0;
while(1)
{
for (a=0;a<50000;a++); //全部位均為零,LED全亮
{
P0=0x00;
}
for (a=0;a<50000;a++); //最低位為1,其余位為零,即最低位滅,其余位亮
{
P0=0x01;
}
for (a=0;a<50000;a++);
{
P0=0x02;
}
for (a=0;a<50000;a++);
{
P0=0x04;
}
for (a=0;a<50000;a++);
{
P0=0x08;
}
for (a=0;a<50000;a++);
{
P0=0x10;
}
for (a=0;a<50000;a++);
{
P0=0x20;
}
for (a=0;a<50000;a++);
{
P0=0x40;
}
for (a=0;a<50000;a++);
{
P0=0x80;
}
}
}
哎,對了,LED燈接的是P1口,數(shù)碼管接的是P0口,應(yīng)該控制P1口才對呀?為啥控制P0口也能讓LED亮滅呢???
我也有同感,???
歡迎光臨 (http://www.torrancerestoration.com/bbs/) | Powered by Discuz! X3.1 |