打印

非常佩服匠人的bit真气**

[复制链接]
楼主: ayb_ice
手机看帖
扫描二维码
随时随地手机跟帖
81
ayb_ice|  楼主 | 2008-6-5 15:36 | 只看该作者 回帖奖励 |倒序浏览

回去测试了一下

确实和优化有关系,但CW就是优化很低也不行。。。

使用特权

评论回复
82
hotpower| | 2008-6-6 02:00 | 只看该作者

实际中俺不会用此无效率的构想,俺倒认为phoenixmy的方法很实

本不想参与此无意义的讨论~~~

因为用N个NOP即N个指令周期的所以精准延时俺从没遇到或采用过...

理由很简单:

它太浪费空间,因为本意是凑够N个NOP来N个指令周期,那么只要指令运行得到

N个指令周期就算正确.

那你不要管我用什么宏或指令.

所以俺更倾向phoenixmy的方法即用for+nop补偿的方法来实现.

再"精准延时"实际RTC或PWM或测试脉宽才是重要的,没有什么芯片要"精准延时",

它们都是由最小,典型和最大来表述的.

在主题下有用if的,俺感觉很奇怪...这是予处理指令吗???

俺没这样用过,没发言权,但俺保留#if的权利~~~

如果if正确,那为何不用效率更高的for或while呢???

最好用dsp的rpt指令~~~

郁闷~~~有人出这样的问题~~~

使用特权

评论回复
83
testcode| | 2008-6-6 03:05 | 只看该作者

赞同用"for+nop"方式...

使用特权

评论回复
84
xwj| | 2008-6-6 08:19 | 只看该作者

要迟到,语法点亮错误晚点再修正。

使用特权

评论回复
85
ayb_ice|  楼主 | 2008-6-6 09:17 | 只看该作者

回80L

这个宏我也仅仅是在模拟SPI,IIC接口时用到,一般在1~10个NOP之间,主要是为了平衡CLK的高低电平时间。。。

使用特权

评论回复
86
phoenixmy| | 2008-6-6 09:26 | 只看该作者

nop少的话就没必要宏了



直接写上就行,反正也不多么

使用特权

评论回复
87
ayb_ice|  楼主 | 2008-6-6 14:22 | 只看该作者

宏修改方便

使用特权

评论回复
88
程序匠人| | 2008-6-6 15:41 | 只看该作者

xwj: 能不能补充一下你的编译结果

使用特权

评论回复
89
xwj| | 2008-6-6 15:59 | 只看该作者

本来想写个全能型的,结果编译出来结果不对:-)

#include <REG52.H>
#include <intrins.h>

sbit P1_1    = P1^1;

unsigned char  NOPBUF;

//------------------------------      //宏开始
#define __NOPX__(a)                            
    if ((a)&(0x01))    {_nop_();}               
    if ((a)>1)    {NOPBUF=((a)/2-1);}           
    if ((a)>3)    while(--NOPBUF)
//      ------------------------------//宏结束

void main(void)
{
    unsigned char i;
    __NOPX__(1);
    P1_1=~P1_1;
    __NOPX__(2);
    P1_1=~P1_1;
    __NOPX__(3);
    P1_1=~P1_1;
    __NOPX__(4);
    P1_1=~P1_1;
    __NOPX__(5);
    P1_1=~P1_1;
    __NOPX__(6);
    P1_1=~P1_1;
    __NOPX__(7);
    P1_1=~P1_1;
    __NOPX__(8);
    P1_1=~P1_1;
    __NOPX__(9);
    __NOPX__(10);
    __NOPX__(11);
    __NOPX__(12);
    __NOPX__(100);
    __NOPX__(111);
    while(1)
    {
        __NOPX__(i);
        i++;
    }
}


//本程序由xwj设计的UltraEdit脚本加亮显示,如需要脚本访问我的Blog 或发送邮件至:xwjfile@21cn.com

使用特权

评论回复
90
xwj| | 2008-6-6 16:05 | 只看该作者

看看Keil编译的结果:

很明显,if参与了代码,逻辑有问题

无端的多出了这些代码:
    SJMP     C:0009
    DJNZ     NOPBUF(0x08),C:0006
少于4的虽然逻辑对了,但多执行一个SJMP(2周期)
4个周期以上的还是对的

a只能作为常量,做变量用的话所有语句都会被理解成程序,全部参与编译,全乱套了

    15: void main(void) 
    16: { 
    17:     unsigned char i; 
    18:         __NOPX__(1); 
C:0x0003    00       NOP      
C:0x0004    8003     SJMP     C:0009
C:0x0006    D508FD   DJNZ     NOPBUF(0x08),C:0006
    19:         P1_1=~P1_1; 
C:0x0009    B291     CPL      P1_1(0x90.1)
    20:         __NOPX__(2); 
C:0x000B    E4       CLR      A
C:0x000C    F508     MOV      NOPBUF(0x08),A
C:0x000E    8003     SJMP     C:0013
C:0x0010    D508FD   DJNZ     NOPBUF(0x08),C:0010
    21:         P1_1=~P1_1; 
C:0x0013    B291     CPL      P1_1(0x90.1)
    22:         __NOPX__(3); 
C:0x0015    00       NOP      
C:0x0016    E4       CLR      A
C:0x0017    F508     MOV      NOPBUF(0x08),A
C:0x0019    8003     SJMP     C:001E
C:0x001B    D508FD   DJNZ     NOPBUF(0x08),C:001B
    23:         P1_1=~P1_1; 
C:0x001E    B291     CPL      P1_1(0x90.1)
    24:         __NOPX__(4); 
C:0x0020    750801   MOV      NOPBUF(0x08),#0x01
C:0x0023    D508FD   DJNZ     NOPBUF(0x08),C:0023
    25:         P1_1=~P1_1; 
C:0x0026    B291     CPL      P1_1(0x90.1)
    26:         __NOPX__(5); 
C:0x0028    00       NOP      
C:0x0029    750801   MOV      NOPBUF(0x08),#0x01
C:0x002C    D508FD   DJNZ     NOPBUF(0x08),C:002C
    27:         P1_1=~P1_1; 
C:0x002F    B291     CPL      P1_1(0x90.1)
    28:         __NOPX__(6); 
C:0x0031    750802   MOV      NOPBUF(0x08),#0x02
C:0x0034    D508FD   DJNZ     NOPBUF(0x08),C:0034
    29:         P1_1=~P1_1; 
C:0x0037    B291     CPL      P1_1(0x90.1)
    30:         __NOPX__(7); 
C:0x0039    00       NOP      
C:0x003A    750802   MOV      NOPBUF(0x08),#0x02
C:0x003D    D508FD   DJNZ     NOPBUF(0x08),C:003D
    31:         P1_1=~P1_1; 
C:0x0040    B291     CPL      P1_1(0x90.1)
    32:         __NOPX__(8); 
C:0x0042    750803   MOV      NOPBUF(0x08),#0x03
C:0x0045    D508FD   DJNZ     NOPBUF(0x08),C:0045
    33:         P1_1=~P1_1; 
C:0x0048    B291     CPL      P1_1(0x90.1)
    34:         __NOPX__(9); 
C:0x004A    00       NOP      
C:0x004B    750803   MOV      NOPBUF(0x08),#0x03
C:0x004E    D508FD   DJNZ     NOPBUF(0x08),C:004E
    35:         __NOPX__(10); 
C:0x0051    750804   MOV      NOPBUF(0x08),#0x04
C:0x0054    D508FD   DJNZ     NOPBUF(0x08),C:0054
    36:         __NOPX__(11); 
C:0x0057    00       NOP      
C:0x0058    750804   MOV      NOPBUF(0x08),#0x04
C:0x005B    D508FD   DJNZ     NOPBUF(0x08),C:005B
    37:         __NOPX__(12); 
C:0x005E    750805   MOV      NOPBUF(0x08),#0x05
C:0x0061    D508FD   DJNZ     NOPBUF(0x08),C:0061
    38:         __NOPX__(100); 
C:0x0064    750831   MOV      NOPBUF(0x08),#0x31
C:0x0067    D508FD   DJNZ     NOPBUF(0x08),C:0067
    39:         __NOPX__(111); 
C:0x006A    00       NOP      
C:0x006B    750836   MOV      NOPBUF(0x08),#0x36
C:0x006E    D508FD   DJNZ     NOPBUF(0x08),C:006E
    40:         while(1) 
    41:         { 
    42:                 __NOPX__(i); 
C:0x0071    E509     MOV      A,0x09
C:0x0073    30E001   JNB      0xE0.0,C:0077
C:0x0076    00       NOP      
C:0x0077    E509     MOV      A,0x09
C:0x0079    D3       SETB     C
C:0x007A    9401     SUBB     A,#0x01
C:0x007C    4006     JC       C:0084
C:0x007E    E509     MOV      A,0x09
C:0x0080    13       RRC      A
C:0x0081    14       DEC      A
C:0x0082    F508     MOV      NOPBUF(0x08),A
C:0x0084    E509     MOV      A,0x09
C:0x0086    D3       SETB     C
C:0x0087    9403     SUBB     A,#0x03
C:0x0089    4003     JC       C:008E
C:0x008B    D508FD   DJNZ     NOPBUF(0x08),C:008B
    43:                 i++; 
C:0x008E    0509     INC      0x09
    44:         } 
C:0x0090    80DF     SJMP     C:0071

使用特权

评论回复
91
xwj| | 2008-6-6 16:09 | 只看该作者

而且,不同的优化级别,编译出的代码也不同

不同变压器当然也会不同,

因此必须得验证后再使用

使用特权

评论回复
92
xielihong| | 2008-6-6 16:30 | 只看该作者

xwj的修改版

#define __NOPX__(a)            
do{                            
    unsigned char  NOPBUF;     
    if ((a)&(0x01))  _nop_();  
    NOPBUF=((a)>>1);           
    while(--NOPBUF) ;          
}while(0)

xwj的修改版,编译出来的代码是一样的,感觉这样写会好一点

使用特权

评论回复
93
xwj| | 2008-6-6 21:12 | 只看该作者

LS那样是不行的

至少这一句不能放在宏里面,或者在能确认风险时用R7或ACC
unsigned char  NOPBUF;

因为很可能会多处调用__NOPX__(a),那就会存在多个unsigned char  NOPBUF;了

使用特权

评论回复
94
hotpower| | 2008-6-6 22:23 | 只看该作者

真想不通for+nop有什么不好~~~何必用宏伤脑筋

有些编译器宏是不允许设置断点的~~~

使用特权

评论回复
95
kabour| | 2008-6-7 09:37 | 只看该作者

。。。。。。。。

空白

使用特权

评论回复
96
zwjgg| | 2008-6-7 23:47 | 只看该作者

战歌位置,慢慢看

使用特权

评论回复
97
wxj1952| | 2008-6-8 10:08 | 只看该作者

xwj说俺瞎嚷嚷,能不能再嚷嚷一个与别人不一样的出来?

这里跟优化没有任何关系。而且适用各类宏汇编器。

 #pragma small src

#pragma asm
NOPX  MACRO NUM
    REPT NUM
    NOP
    ENDM
ENDM
#pragma endasm


 void main(void)
{
 __asm NOPX 5   // 输出5个NOP.

while(1);
}

有没有和我一样的?那是我的悲哀。那就再写一个。



使用特权

评论回复
98
phoenixmy| | 2008-6-8 10:11 | 只看该作者

有么



DSP就有REPT指令

使用特权

评论回复
99
gooog| | 2008-6-8 10:22 | 只看该作者

回匠人

不能用#if是不是因为条件编译不能使用变量的缘故?

使用特权

评论回复
100
wxj1952| | 2008-6-8 10:32 | 只看该作者

有件事不明白。

站长的汇编比C做得好,那是显然的。那么18L的软件陷阱是不是复杂了?还是我不明白其中奥妙。
    用REPT宏指令,一条宏调用可以DB 65536字节“0”或其它。例如:
    
        NOPX 1024

没有REPT宏指令的汇编器,大概没有。再古老一点的ASM 都有。INTEL创始,大家以此为蓝本。谁也不笨。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则