2012-10-04 09:21:31 GoodShot 阅读数 10015

想要调用子程序,只要输入 LCALL XXXX,XXXX代表你子程序的名字 如一个延时子程序 LCALL DELY1MS 这是调用一个延时1毫秒的延时子程序 当然,子程序的名字可以自己定 DELY1MS: 这个名字一定要与调用中出现的名字一样,否则的话,调用的就不是这个子程序了

DELY1MS:

MOV R7,#250

DL1: NOP

         NOP

        DJNZ R7,DL1

RETRET的作用是子程序返回。调用一个子程序,当单片机执行到RET语句的时候,单片机就会返回到调用的地方并继续向下执行。

下面给你一个例程:

闪烁灯

ORG 00H

AJMP START

ORG 30H

START:

             MOV P0,#00H

LCALL DELY;调用延时子程序

MOV P0,#0FFH

LCALL DELY;调用延时子程序

AJMP START

DELY:

MOV R7,#250

DL1:MOV R6,#250

DJNZ R6,$

DJNZ R7,DL1

RET

 

END

2013-11-01 23:27:12 tzshlyt 阅读数 2135
晶振频率:12M 
(一)原程序:
delay: mov  r7,#200     
   d1: mov  r6,#125      
   d2: djnz  r6,d2          
       djnz  r7,d1          
       ret                      
分析过程:
delay: mov   r7,#200        r7=200   执行需1us
   d1: mov   r6,#125        r6=125      1us
   d2: djnz  r6,d2          r6=124   直到r6=0,共执行125次125*2us
       djnz  r7,d1          r7=199       2us
   d1: mov   r6,#125        r6=125
   d2: djnz  r6,d2          r6=124
       djnz  r7,d1          r7=198
         *
         *   共执行200次
         *
   d1: mov   r6,#125        r6=125
   d2: djnz  r6,d2          r6=124
       djnz  r7,d1          r7=1
   d1: mov   r6,#125        r6=124
   d2: djnz  r6,d2          r6=123
       djnz  r7,d1          r7=0      执行下一条程序
       ret                  2us
延时时间为:1+(1+125*2+2)*200+2=50603us

公式:精确延时时间=3+3*r7+2*r7*r6


(二)原程序:

delay: mov   r7,#10
   d1: mov   r6,#200
   d2: mov   r5,#248
   d3: djnz  r5,d3
       djnz  r6,d2
       djnz  r7,d1
       ret
延时时间为:1+[1+(1+248*2+2)*200+2]*10+2=998033us
公式:精确延时时间=1+[1+(1+r5*2+2)*r6+2]*r7+2=3+3*r7+3*r7*r6+2*r7*r6*r5

加上lcall delay的时间,需加 2us,则最终时间就为两条程序执行间隔时间。
   
2009-11-13 12:29:00 tpstech 阅读数 3099

 STC12系列1T单片机的延时程序,自己写的,用汇编指令来算算,还可以,需要的就用吧,反正好久没更新BLOG了,想起来就随便贴一点东西。。还有用的是22.1184MHZ的晶振。。

#include <intrins.h>
//**********************************************************
//函数名称:Delay1ms(unsigned int i)
//函数功能:延时i*1ms的子程序(对应于22.1184Mhz晶振)  
//形式参数:unsigned int i
//行参说明:无
//返回参数:无
//使用说明:i为要延时的时间长度,单位是MS,最大可以延时65536 ms
//**********************************************************
void Delay1ms(unsigned int i)
{
unsigned char j,k;
do{
  j = 44;
  do{
   k = 100;
   do{
    _nop_();
   }while(–k);    
  }while(–j);
}while(–i);

}

//**********************************************************
//函数名称:Delay1us(void)
//函数功能:延时1us的子程序(对应于22.1184Mhz晶振)  
//形式参数:无
//行参说明:无
//返回参数:无
//使用说明:调用一次,延时一微秒
//**********************************************************
void Delay1us(void)
{
unsigned char i=2;
do{
_nop_();
}while(–i);

}
//**********************************************************
//函数名称:Delay10us(unsigned char i)
//函数功能:延时i*10us的子程序(对应于22.1184Mhz晶振)  
//形式参数:无
//行参说明:无
//返回参数:无
//使用说明:i为要延时的时间长度,单位是US,最大可以延时250 ms
//**********************************************************
void Delay10us(unsigned char i)
{
   unsigned char j;
do{
  j = 30;
  do{
   _nop_();
   }while(–j);
}while(–i);
}

2011-05-23 15:13:00 cheng110110 阅读数 695

void delay0.2s(void)

 unsigned char i,j,k; 
 for(i=20;i>0;i--) 
 for(j=20;j>0;j--) 
 for(k=248;k>0;k--)
}
;


((K*2)+3)*2+3)*I+5

 

我们用汇编语言写单片机延时10ms的程序(用的是12MHz晶振的  MCS-51),可以编写下面的程序来实现:

MOV R5,#5      ①

 D1:   MOV R6,#4      ②

 D2:     MOV R7,#248    ③

          DJNZ R7,$       ④

          DJNZ R6,D2      ⑤

      DJNZ R5,D1      ⑥

      RET            ⑦

这个延时程序共有七条指令,现在就每一条指令执行的次数和所耗时间进行分析:

第一条,                   MOV R5,#5 在整个程序中只执行一次,且为单周期指令,所以耗时1μs,

第二条,                   MOV R6,#4 看⑥的指令可知,只要R5-1不为0,就会返回执行这条指令,共执行了R5次,共耗时5μs,

第三条,                   MOV R7,#248 同第二条类似,只要R6-1不为0,就会返回执行这条指令,同时受到外部循环R5的控制,共耗时R5*R6*1=20μs,

第四条,                   DJNZ  R7,$ 只要R7-1不为0,就执行这条指令,同时受到外部循环的控制,由于该指令是双周期指令,共耗时为R7*R6*R5*2=9920μs,

第五条,                   DJNZ  R6,D2 只要R6-1不为0,就反复执行此条指令(内循环R6次),又受外循环R7的控制,共耗时R6*R5*2=40μs,

第六条,                   DJNZ  R5,D1 只要R5-1不为0,就反复执行此条指令,耗时为R5*2=10μs,

第七条,                   RET 此指令为双周期指令,耗时为2μs,

我们也要考虑在调用子程序时用到LCALL指令,耗时2μs,最后可以得到总的延时为:1+5+20+9920+40+10+2+2=10000μs=10ms

我们可以总结延时总时间的公式:

延时总时间=[(2*一层循环次数+3)*二层循环次数+3]*三层循环次数+5

注意此公式只适用于三层以内的循环。

 

DLY10S : MOV R5,100 ;2指令 4us
DLY10S1: MOV R6,200 ;2指令 4us
DLY10S2: MOV R7,248 ;2指令 4us
DLY10S3:
DJNZ R7,DLY10S3;248*2+4----------------->2指令A = 248*2*2us
DJNZ R6,DLY10S2;(248*2+4)*200+4 -------->2指令B =(A+2a+2b)*200*2us
DJNZ R5,DLY10S1;[(248*2+4)*200+4]*100+4->2指令C =(B+2a+2a+2b)*100*2us
RET ;1指令 2us

总时间=C+1*2us;此处的+1是“RET”的时间;上述注释中的“+2a”是MOV指令周期,注意对应的循环;上述注释的“+2b”是DJNZ本身的2个机器周期;应该是这样的吧,你的程序可能有问题。

 

 

 

 

 

 

 

 

1  使用定时器/计数器实现精确延时 

  单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。

 

  在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。

 


2  软件延时与时间计算

 

  在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。信息来源"岁月联盟"

2.1  短暂延时

信息来自"岁月联盟"


  可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:

 

  void Delay10us( ) {
    _NOP_( );
    _NOP_( );
    _NOP_( );
    _NOP_( );
    _NOP_( );
    _NOP_( );
  }


  Delay10us( )函数中共用了6个_NOP_( )语句,每个语句执行时间为1 μs。主函数调用Delay10us( )时,先执行一个LCALL指令(2 μs),然后执行6个_NOP_( )语句(6 μs),最后执行了一个RET指令(2 μs),所以执行上述函数时共需要10 μs。  可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用/[4/],以实现较长时间的延时;但需要注意,如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时间将是42 μs,而不是40 μs。这是因为执行Delay40us( )时,先执行了一次LCALL指令(2 μs),然后开始执行第一个Delay10us( ),执行完最后一个Delay10us( )时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),则也要先执行一次LCALL指令(2 μs),然后执行两次Delay40us( )函数(84 μs),所以,实际延时时间为86 μs。简言之,只有最内层的函数执行RET指令。该指令直接返回到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),此时的延时时间为82 μs。通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。

2010-07-23 11:48:00 djimon 阅读数 9217

延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器

周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指

令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者

   我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如

在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何

实现的呢?下面让我们先来了解一些相关的概念。

一、机器周期和指令周期

1.机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度,

51 单片机的一个机器周期包括12 个时钟振荡周期,也就是说如果51 单片机采用12MHz 晶振,那么执行

一个机器周期就只需要1μs;如果采用的是6MHz 的晶振,那么执行一个机器周期就需要2 μs。

   2 .指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。

在51 单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个

机器周期),四周期指令(执行这条指令需要四个机器周期)。除了乘、除两条指令是四周期指令,其余均

为单周期或双周期指令。也就是说,如果51 单片机采用的是12MHz 晶振,那么它执行一条指令一般只需

1~2 微秒的时间;如果采用的是6MH 晶振,执行一条指令一般就需2~4 微秒的时间。

   现在的单片机有很多种型号,但在每个型号的单片机器件手册中都会详细说明执行各种指令所需的机

器周期,了解以上概念后,那么可以依据单片机器件手册中的指令执行周期和单片机所用晶振频率来完成

需要精确延时时间的延时程序。

二、延时指令

   在单片机编程里面并没有真正的延时指令,从上面的概念中我们知道单片机每执行一条指令都需要一

定的时间,所以要达到延时的效果,只须让单片机不断地执行没有具体实际意义的指令,从而达到了延时

的效果。

1.数据传送指令 MOV

   数据传送指令功能是将数据从一个地方复制、拷贝到另一个地方。

   如:MOV R7,#80H   ;将数据80H 送到寄存器R7,这时寄存器R7 里面存放着80H,就单这条

指令而言并没有任何实际意义,而执行该指令则需要一个机器周期。

2.空操作指令 NOP

   空操作指令功能只是让单片机执行没有意义的操作,消耗一个机器周期。

3.循环转移指令 DJNZ

   循环转移指令功能是将第一个数进行减1 并判断是否为0,不为0 则转移到指定地点;为0 则往下执行。

   如:DJNZ R7,KK ;将寄存器R7 的内容减1 并判断寄存器R7 里的内容减完1 后是否为0,如果

   不为0 则转移到地址标号为KK 的地方;如果为0 则执行下一条指令。这条指令需要2 个机器周期。

   利用以上三条指令的组合就可以比较精确地编写出所需要的延时程序。

三、1 秒延时子程序、流程图及时间计算 (以单片机晶振为12MHz 为例,1 个机器周期需要1μs)

了解了以上的内容,现在让我们来看看

程序总共所需时间:1+10+2560+330240+660480+5120+20+2=998433 μs≈1S

   在这里运行这段程序共需998433 μs,还差1567μs 才达到1S 的,所以想要达到完美的1S 延时,需

要在返回指令RET 前再添加一些指令让它把1567μs 的延时完成。有兴趣的读者可以自己试着添加完成。

最后补充一点,编写程序时一般将延时程序编写成独立的子程序,而所谓子程序也就是一个实现某个功能

的小模块。这样在主程序中就可以方便地反复调用编写好的延时子程序。

   小提示:循环转移指令(DJNZ )除了可以给定地址标号让其跳转外,还可以将地址标号改成$,这样

程序就跳回本指令执行。例如:

   DJNZ R7,$ ;R7 内容减1 不为0,则再次执行本指令;为0 则往下执行,当R7 的值改为10

时,则执行完该条程序所需的时间为2*10=20 μs。

51单片机汇编延时程序算法详解

将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。   

指令周期、机器周期与时钟周期

  指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。

  时钟周期:也称为振荡周期,一个时钟周期 =晶振的倒数。

  MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。

  MCS-51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1μs。

  程序分析

  例1 50ms 延时子程序:

  DEL:MOV R7,#200 ①

  DEL1:MOV R6,#125 ②

  DEL2:DJNZ R6,DEL2 ③

  DJNZ R7,DEL1 ④

  RET ⑤

  精确延时时间为:1+(1*200)+(2*125*200)+(2*200)+2

  =(2*125+3)*200+3 ⑥

  =50603μs

  ≈50ms

  由⑥整理出公式(只限上述写法)延时时间=(2*内循环+3)*外循环+3 ⑦

详解:DEL这个子程序共有五条指令,现在分别就 每一条指令 被执行的次数和所耗时间进行分析。

  第一句:MOV R7,#200 在整个子程序中只被执行一次,且为单周期指令,所以耗时1μs

  第二句:MOV R6,#125 从②看到④只要R7-1不为0,就会返回到这句,共执行了R7次,共耗时200μs

  第三句:DJNZ R6,DEL2 只要R6-1不为0,就反复执行此句(内循环R6次),又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*R6*R7μs。

  例2 1秒延时子程序:

  DEL:MOV R7,#10 ①

  DEL1:MOV R6,#200 ②

  DEL2:MOV R5,#248 ③

  DJNZ R5,$ ④

  DJNZ R6,DEL2 ⑤

  DJNZ R7,DEL1 ⑥

  RET ⑦

  对每条指令进行计算得出精确延时时间为:

   1+(1*10)+(1*200*10)+(2*248*200*10)+(2*200*10)+(2*10)+2

  =[(2*248+3)*200+3]*10+3 ⑧

  =998033μs≈1s

  由⑧整理得:延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑨

  此式适用三层循环以内的程序,也验证了例1中式⑦(第三层循环相当于1)的成立。

  注意,要实现较长时间的延时,一般采用多重循环,有时会在程式序里加入NOP指令,这时公式⑨不再适用,下面举例分析。

  例3仍以1秒延时为例

  DEL:MOV R7,#10 1指令周期1

  DEL1:MOV R6,#0FFH 1指令周期10

  DEL2:MOV R5,#80H 1指令周期255*10=2550

  KONG:NOP 1指令周期128*255*10=326400

  DJNZ R5,$ 2指令周期2*128*255*10=652800

  DJNZ R6,DEL2 2指令周期2*255*10=5110

  DJNZ R7,DEL1 2指令周期2*10=20

  RET 2

  延时时间=1+10+2550+326400+652800+5110+20+2 =986893μs约为1s

  整理得:延时时间=[(3*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑩

  结论:针对初学者的困惑,对汇编程序的延时算法进行了分步讲解,并就几种不同写法分别总结出相应的计算公式,只要仔细阅读例1中的详解,并用例2、例3来加深理解,一定会掌握各种类型程序的算法并加以运用。

单片机延时子程序

1)延时为:20ms 晶振12M

1+(1+2*248+2)*4+1+1+1=20000US=20MS

用汇编..优点就是精确...

缺点就是算有点复杂.

DELAY20MS:

MOV R7,#4

D1:

MOV R6,#248

DJNZ R6,$

DJNZ R7,D1

NOP

NOP

RET

2)一些通过计算51汇编指令得出的软延时子程序

;*****************************************************************   

;延时10uS   

;*****************************************************************   

  

time10us:               mov     r5,#05h                 ;11us   

                        djnz    r5,$   

                        ret  

  

;*****************************************************************   

;延时50uS   

;*****************************************************************   

  

time50us:               mov     r5,#19h                 ;51us   

                        djnz    r5,$   

                        ret  

  

;*****************************************************************   

;延时100uS   

;*****************************************************************   

  

time100us:              mov     r5,#31h                 ;99.6us   

                        djnz    r5,$   

                        ret  

  

;*****************************************************************   

;延时200uS   

;*****************************************************************   

  

time200us:              mov     r5,#64h                 ;201us   

                        djnz    r5,$   

                        ret  

  

;*****************************************************************   

;延时250uS   

;*****************************************************************   

  

time250us:              mov     r5,#7ch                 ;249.6us   

                        djnz    r5,$   

                        ret  

  

;*****************************************************************   

;延时350uS   

;*****************************************************************   

  

time350us:              mov     r5,#0afh                 ;351us   

time350us_1:            djnz    r5,time350us_1   

                        ret  

  

;*****************************************************************   

;延时500uS   

;*****************************************************************   

  

time500us:              mov     r5,#0fah                 ;501us   

time500us_1:            djnz    r5,time500us_1   

                        ret  

  

;*****************************************************************   

;延时1mS   

;*****************************************************************   

  

time1ms:                mov     r5,#0fah                ;1001us   

time1ms_1:              nop  

                        nop  

                        djnz    r5,time1ms_1   

                        ret  

  

;*****************************************************************   

;延时2.5mS   

;*****************************************************************   

  

time2_5ms:              mov     r5,#05h          ;2.496ms   

time2_5ms_1:            mov     r6,#0f8h         ;497us   

                        djnz    r6,$   

                        djnz    r5,time2_5ms_1   

                        ret  

  

;*****************************************************************   

;延时10mS   

;*****************************************************************   

  

time10ms:               mov    r5,#14h         ;10.262ms   

time10ms_1:             mov    r6,#0ffh        ;511us   

                        djnz   r6,$   

                        djnz   r5,time10ms_1   

                        ret  

  

;*****************************************************************   

;延时50mS   

;*****************************************************************   

  

time50ms:               mov    r5,#63h         ;49.996ms   

time50ms_1:             mov    r6,#0fbh        ;503us   

                        djnz   r6,$   

                        djnz   r5,time50ms_1   

                        ret  

  

;*****************************************************************   

;延时100mS   

;*****************************************************************   

  

time100ms:              mov     r5,#0c3h        ;100.036ms   

time100ms_1:            mov     r6,#0ffh        ;511us   

                        djnz    r6,$   

                        djnz    r5,time100ms_1   

                        ret  

  

;*****************************************************************   

;延时200mS   

;*****************************************************************   

  

time200ms:              mov     r5,#02h         ;250.351ms   

time200ms_1:            mov     r6,#0f4h        ;125.173ms   

time200ms_2:            mov     r7,#0ffh        ;511us   

                        djnz    r7,$   

                        djnz    r6,time200ms_2   

                        djnz    r5,time200ms_1   

                        ret  

  

;*****************************************************************   

;延时500mS   

;*****************************************************************   

  

time500ms:              mov    r5,#04h         ;500.701ms   

time500ms_1:            mov    r6,#0f4h        ;125.173ms   

time500ms_2:            mov    r7,#0ffh        ;511us   

                        djnz   r7,$   

                        djnz   r6,time500ms_2   

                        djnz   r5,time500ms_1   

                        ret  

  

;*****************************************************************   

;延时1S   

;*****************************************************************   

  

time1s:                 mov    r5,#08h         ;1001.401ms   

time1s_1:               mov    r6,#0f4h        ;125.173ms   

time1s_2:               mov    r7,#0ffh        ;511us   

                        djnz   r7,$   

                        djnz   r6,time1s_2   

                        djnz   r5,time1s_1   

                        ret

12M晶振 机器周期为1US  NOP为单周期指令 DJNZ为双周期指令.

3)

;;晶振12MHZ,延时1秒  

   

   

   

DELAY:MOV   72H,#100  

LOOP3:MOV   71H,#100  

LOOP1:MOV   70H,#47  

LOOP0:DJNZ   70H,LOOP0  

              NOP    

              DJNZ   71H,LOOP1  

              MOV   70H,#46  

LOOP2:DJNZ   70H,LOOP2  

              NOP  

              DJNZ   72H,LOOP3  

              MOV   70H,#48  

LOOP4:DJNZ   70H,LOOP4

4);延时1分钟子程序,F=6MHz

;程序已测过,延时时间60,000,000.0uS

delay60s:mov r3,#228

         mov r2,#253

         mov r1,#219

loop1:   djnz r1,$

         djnz r2,loop1

         djnz r3,loop1

         nop

         ret

5)计算机反复执行一段程序以达到延时的目的称为软件延时,单片机程序中经常需要短时间的延时,但是相当一部分人对延时程序很模糊,对延时程序的算法不够了解,在这里我以12MHz晶振和两个经典延时子程序为例,详细分析单片机汇编延时程序。

何为时钟周期、机器周期、和指令周期?

时钟周期:也就是振荡周期,以12MHz的时钟脉冲为例,那时钟周期就为(1/12000000)s=(1/12)us;

机器周期:1个机器周期=6个状态周期=12个时钟周期=1us;

指令周期:CPU执行一条指令所需要的时间称为指令周期,指令周期是以机器周期为单位的,不同的指令所需的机器周期不一定相同,可参考51单片机指令速查表。

        由上可得:CPU执行一条单周期指令,需要1us;执行一条双周期指令需要2us。

        下面是具体的延时子程序分析:

0.1s延时子程序(12MHz晶振):

           MOV R7,#200   ;单周期指令(1us)

D1:     MOV R6,#250   ;单周期指令(1us)

           DJNZ R6,$      ;双周期指令(2us)//该指令自身执行R6次

           DJNZ R7,D1     ;双周期指令(2us)//D1执行R7次

           RET            ;双周期指令(2us)

T=1+(1+2*R6+2)*R7+2

   =100603us

   ≈0.1s

0.5s延时子程序(12MHz晶振):

           MOV R7,#5     ;单周期指令(1us)

D1:     MOV R6,#200   ;单周期指令(1us)

D2:     MOV R5,#250   ;单周期指令(1us

           DJNZ R5,$      ;双周期指令(2us)//该指令自身执行R5次

           DJNZ R6,D2     ;双周期指令(2us)//D2执行R6次

           DJNZ R7,D1     ;双周期指令(2us)//D1执行R7次

           RET            ;双周期指令(2us)

T=1+[1+(1+2*R5+2)*R6+2]*R7+2

   =503018us

   ≈0.5s

6) 51单片机经典流水灯程序,在51单片机的P2口接上8个发光二极管,产生流水灯的移动效果。

                    ORG        0                   ;程序从0地址开始

START:      MOV      A,#0FEH     ;让ACC的内容为11111110

LOOP:         MOV      P2,A            ;让P2口输出ACC的内容

                     RR          A                  ;让ACC的内容左移

                     CALL     DELAY       ;调用延时子程序

                     LJMP     LOOP          ;跳到LOOP处执行

;0.1秒延时子程序(12MHz晶振)===================

DELAY:      MOV      R7,#200      ;R7寄存器加载200次数

D1:               MOV      R6,#250      ;R6寄存器加载250次数

                     DJNZ     R6,$             ;本行执行R6次

                     DJNZ     R7,D1          ;D1循环执行R7次

                     RET                            ;返回主程序

                     END                           ;结束程序

51单片机第一课

阅读数 63

没有更多推荐了,返回首页