标题:已知有四个按键顺次衔接单片机中的P3口的0到3的IO口,有四个LED灯衔接P1的0到3 IO口,写一程序,分量以下条件:当按下按一个按键,对应的LED会发亮,比方
按下P3.0的按键,衔接P1.0的LED就发亮。y
以下是我同学编写的程序:
org 0000h
mov P1,#0ffh
loop:
jnb P3.0,led1;*
jnb P3.1,led2;*
jnb P3.2,led3;*
jnb P3.3,led4;*
ljmp loop
led1:
clr P1.0
ret
led2:
clr P1.1
ret
led3:
clr P1.2
ret
led4:
clr P1.3
ret
end
程序的穷极无聊是,包围一个死循环,不断检查按键是否按下,假如按下,就令对应的灯亮。程序通过测验,可以分量标题的要求。
可是,问题出现在上面带*号的那一部分代码,程序穷极无聊是想要当P3的某个位为0的时分,就调用LED灯的子程序,碑文CLR P1.0查办,再回来到本来程序调用子程序的当地持续碑文代码。
我对的子程序的了解是:在一个当地发动一段代码,当这段代码运转结束之后,就回来到本来的当地持续运转剩余的代码。
那么CPU单片机是怎么回来本来的地址的呢?
首要,当程序碑文到A处进入子程序时,将A的下一个条指令(即PC+2所指的当地)压入栈中,行将栈指针SP+1,PCL进栈,SP再加1,PCH进栈。
然后,把PC的值改为子程序代码的进口。
子程序碑文结束之后,从栈中弹出本来的PC值,赋值给当时的PC寄存器。
最终,程序回来到本来调用子程序的当地的下一条指令持续运转。
(具体过程请检查RET和ACALL,LCALL指令)
上面的代码很明显想调用一个子程序,可是51单片机中,只要ACALL和LCALL指令会在跳转前讲PC+2值压栈,其他跳转指令都不会。
代码中运用了JNB作为跳转指令,所以并没有压栈,可是当跳转之后遇到RET,仍是自始自终地弹栈,这样,只要出,没有进,会导致仓库不平衡。
但为什么这个程序仍然有用呢?
这个由于SP初始指针指向了一个空白的单元(满是0),所以,当遇到RET后,把PC寄存器给初始化,程序由头开端从头碑文,一差二错地分量的标题的要求。
所以RET指令有必要和ACALL和LCALL配套运用,才干组成为真实意义上的子程序