MOV R0,#08H
MOV A,#0FEH
LOOP: MOV P1,A
LCALL DEL
RR A
DJNZ R0,LOOP
使用DJNZ 指令。为0执行下一指令,不为0跳转。
就可以调用两个子程序了
如果单纯延时,可以用实验的办法,在keilc51里面仿真
void Delay1S(char n)
{
char i,j;
n=n4;
for(;n;n--)
{
for(i=6;i;i++)
{
for(j=7;j;j++) // 一个循环约为1mS
;
}
}
}
看编译后的汇编:
C:0x0805 7D01 MOV R5,#0x06;j=1,1时钟
C:0x0807 0D INC R5;j++,1时钟
C:0x0808 ED MOV A,R5;A=R5,1时钟
C:0x0809 70FC JNZ C:0807;A=0,2时钟
循环共249次,一个循环共需4个时钟周期,加上第一个赋值语句1周期。
共997uS,加上外层循环,一次约1mS,
如果要精确的延时建议采用中断:
#include "reg51h"
//timer init
void initTimer(void)
{
TMOD=0x2;
TH0=0x6;
TL0=0x6;
}
int T250uS;
char T_mark;
//timer0/counter0 interrupt
void timer0(void) interrupt 1
{
//add your code here
T250uS++;
T_mark=0;
}
void Delay1S(char n)
{
for(;n;n--)
for(T250uS=0;T250uS<4000;)
{
T_mark=1;
while(T_mark);
}
}
//the main fun
void main(void)
{
initTimer();
TR0=1;
ET0=1;
EA=1;
while(1)
{
Delay1S(1);
}
}
子程序的调用,地址入栈是自动的。程序可以编程 *** 作,51单片机是16位的地址,两个字节,汇编语言你可以在程序中,在栈中压入两个字节的地址数据,然后执行RET指令,程序就转向你指定的地址执行。
你说的应该是C语言编程的吧。C语言调用子函数后当然也可以 *** 作栈,但是除非你知道你要做什么,否则不建议在C语言中 *** 作硬件寄存器。
R0~R7,A,PSW要入栈因为是在主程序中用到了这些寄存器,但是中断是不确定什么时候发生的,在中断程序中也要用到这些寄存器,为了在中断中不修改主程序中的这些寄存器,在中断程序发生时,先保存这些寄存器的内容(入栈保护),然后中断使用这些寄存器,用完后出栈恢复这些寄存器的值,程序重新把这些寄存器交回主程序运行
以上就是关于怎样51单片机调用两个子程序全部的内容,包括:怎样51单片机调用两个子程序、51单片机用汇编语言设计1S延时子程序,晶振为12MHz。 (麻烦附上详细计算过程以及详细说明,、51单片机因中断处理,子程序调用时入栈问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)