ORG 0000H ;从地址0开始执行程序
LJMP START ;跳转到START处
START: MOV P1,#0FFH ;关闭P1口的所有LED
MOV P2,#0FFH ;关闭P2口的所有LED
MOV P3,#0FFH ;关闭P3口的所有LED
MOV P0,#0FFH ;关闭P0口的所有LED
NOP
NOP
LCALL DELAY_5 ;调用延迟子程序,准备主程序的运行
LOOP:
NOP
NOP
LCALL STATUS_1 ;调用STATUS-1子程序
NOP
NOP
LCALL STATUS_2 ;调用STATUS-2子程序
NOP
NOP
LCALL STATUS_3 ;调用STATUS-3子程序
NOP
NOP
LCALL STATUS_4 ;调用STATUS-4子程序
NOP
NOP
LJMP LOOP ;跳转到LOOP处形成一个循环
//**************以下为STATUS-1的模块***************//
STATUS_1:
MOV P0, #0FFH ;关闭P0口
MOV P1, #0FFH ;关闭P1 口
MOV R0,#5 ;将5赋给R0
LOOP_1:MOV A,#00H ;将0赋给A
MOV P3,A ;将A中的数值赋给P3口
MOV P2,A ;将A中的数值赋给P2口
NOP
NOP
LCALL DELAY_5 ;调用DELAY-5延迟子程序
CPL A ;将A中的数值取反
MOV P3,A ;将A中的数值赋给P3口
MOV P2,A ;将A中的数值赋给P2口
NOP
NOP
LCALL DELAY_5 ;调用DELAY-5延迟子程序
DJNZ R0,LOOP_1 ;跳回LOOP-1处,循环5次
RET ;返回
//***************以下是STATUS-2的模块***************//
STATUS_2:
MOV P1,#0FH ;P1口的高4位亮,即绿灯亮
MOV P0,#0F0H ;P0口的低4位亮,即红灯亮
NOP
NOP
LCALL DELAY_30 ;调用DELAY-30程序
RET ;返回
//***************以下是STATUS-3的模块*******************//
STATUS_3:
MOV P0, #0FFH ;关闭P0口
MOV P1, #0FFH ;关闭P1口
MOV R1,#5 ;将5赋给R1
LOOP_2:MOV A,#00H ;将0赋给A
MOV P3,A ;将A中的数值赋给P3口
MOV P2,A ;将A中的数值赋给P2口
NOP
NOP
LCALL DELAY_5 ;调用DELAY-5子程序
CPL A ;将A中的数值取反
MOV P3,A ;将A中的数值赋给P3口
MOV P2,A ;将A中的数值赋给P2口
NOP
NOP
LCALL DELAY_5 ;调用DELAY-5子程序
DJNZ R1,LOOP_2 ;跳回LOOP-2处,循环5次
RET ;返回
//****************以下是STSTUS-4的模块****************//
STATUS_4:
MOV P1,#0F0H ;P1口的低4位亮,即红灯亮
MOV P0,#0FH ;P0口的高4位亮,即绿灯亮
NOP
NOP
LCALL DELAY_30 ;调用DELAY-30子程序
RET ;返回
//****************以下是DELAY-5模块******************//
DELAY_5:
MOV R2,#12 ;
LOOP_3:MOV R3,#191 ;
LOOP_4:MOV R4,#200 ;
DJNZ R4,$ ;
DJNZ R3,LOOP_4 ;
DJNZ R2,LOOP_3 ;
RET ;
//****************以下是DELAY-30模块****************** //
DELAY_30:
MOV R5,#75 ;
LOOP_6:MOV R6,#247 ;
LOOP_5:MOV R7,#249 ;
DJNZ R7,$ ;
DJNZ R6,LOOP_5 ;
DJNZ R5,LOOP_6 ;
RET ;
//**************结束**************** //
END
其中的红色部分是我修改的地方,可能有朋友要问了,你不就写了三个字母么?有什么了不起!呵呵,好像也对,但如果拿到那三个字母你再看看?程序还能正常运行么?其实,当初我在学习单片机的时候也对NOP很不以为然,但又来慢慢才意识到INTRL不是吃白饭的!人家总共就造了111个指令,怎么可能弄一个没用的上去呢?从指令的运行来讲:NOP这条指令是没有任何含义的,它唯一的作用是消耗时间,但从保护程序的正确执行来讲,它却是一个大功臣!去搜一搜很多别人写好的程序,总会发现在LCALL,JB,JNB,JC,JNC等指令的前后有它们的身影。为什么呢?
首先需要明确的是:在单片机中,无论是程序还是数字,反映到物理设备上,他们仅仅是一串高低电平而已!
其次还得从指令的格式说起,一般来说汇编语言是单字节指令的,换个话说:有的指令是双字节指令,甚至三字节指令的。当执行单字节指令的时候,指令的格式为:操作码,;而双字节指令则为:操作码,操作数;三字节指令的格式为:操作码,操作数,操作数,操作数;当程序执行单字节指令的时候,PC(program counter)可以保证程序正确地执行,即:先取操作码,后取操作数。而当程序执行到双字节或三字节指令的时候,有时候就会误将第二个操作数当成操作码(注意前面红色部分),从而就出现了程序跑飞的发生。而单字节指令NOP的使用恰好可以保证