原创 由C51精确延时想到的

2009-11-9 20:54 1897 8 8 分类: MCU/ 嵌入式

在网络上一直是一个获取者,惭愧啊。从现在起,分享自己的思考,呵呵。


用海子“面朝大海,春暖花开”的一段诗作为自勉吧,PS,我改了其中的一个字。  


         从今天起,和每一个亲人通信
  告诉他们我的幸福
  那幸福的闪电告诉我的
  我将告诉每一个人


回到正题上,这段时间用Keil C51写程序,需要比较精确的延时,搜了一下,好点子真多啊,让我有点想法的是这一段:


              void delay1(unsigned char i)
              {
                  while(--i);
              }
             心不在焉的编译,看源码:
             ; FUNCTION _delay1 (BEGIN)
             ; SOURCE LINE # 13
             ;---- Variable 'i' assigned to Register 'R7' ----
            ; SOURCE LINE # 14
            0000 ?C0004:
           ; SOURCE LINE # 15
             0000 DFFE DJNZ R7,?C0004
            ; SOURCE LINE # 16
           0002 ?C0006:
           0002 22 RET
           ; FUNCTION _delay1 (END)
           天~~~奇迹出现了......我想这个程序应该已经可以满足一般情况下的需要了。如果列个表格的话:
           i    delay time/us
           1    5
           2    7
           3    9
           ...
用while(--i);产生DJNZ,确实简洁啊,不过要是用嵌套延长时间呢,结果是这样的:


      unsigned char i,j; 
      i="100";
C:0x0003    7E64     MOV      R6,#0x64
      while(--i)
C:0x0005    1E       DEC      R6
C:0x0006    EE       MOV      A,R6
C:0x0007    6008     JZ       C:0011
        {j=100;     while(--j);}
C:0x0009    7F64     MOV      R7,#0x64
C:0x000B    1F       DEC      R7
C:0x000C    EF       MOV      A,R7
C:0x000D    60F6     JZ       C:0005
C:0x000F    80FA     SJMP     C:000B


        连内循环的while(--j);都没有用DJNZ编译。突然想到DJNZ指令是先减一再判断是否到零,那就应该用do{}while(--j);来产生DJNZ指令,结果确实如预期的:


      i="100";
C:0x0011    7E64     MOV      R6,#0x64
      do{ j="100"; do{}while(--j);}while(--i);
C:0x0013    7F64     MOV      R7,#0x64
C:0x0015    DFFE     DJNZ     R7,C:0015
C:0x0017    DEFA     DJNZ     R6,C:0013


        循环变量只能是单字节,呵呵。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /3 下一条