sunshulin 发表于 2012-1-6 20:04:38

关于430单片机的一点小发现 个人认为在榨压430单片机功耗这会有一点小用处

编程序时候发现 for循环语句用“--”要比用“++”执行的快一些 下面是我测试的程序和测试结果
“--”的情况:
简单说一下方法是for循环里反复清零和置位同一管脚,然后用示波器看管脚上的波形
unsigned int n;
for(n=240;n>0;n--)
{
    CLR_BIT( LCD_WR );
    SET_BIT( LCD_WR );
}
编译器生成的汇编代码
http://cache.amobbs.com/bbs_upload782111/files_50/ourdev_710858MQS9LX.jpg
(原文件名:123.jpg)
示波器测试结果
http://cache.amobbs.com/bbs_upload782111/files_50/ourdev_710856XTREZ5.JPG
(原文件名:F0001TEK.JPG)
for(n=0;n<240;n++)
{
    CLR_BIT( LCD_WR );
    SET_BIT( LCD_WR );
}
编译器生成的汇编代码
http://cache.amobbs.com/bbs_upload782111/files_50/ourdev_710859OLU2AM.jpg
(原文件名:1234.jpg)
示波器测试结果
http://cache.amobbs.com/bbs_upload782111/files_50/ourdev_710857FZ3WEW.JPG
(原文件名:F0000TEK.JPG)
更深入剖析应该是这几条汇编指令执行速度 tst.w (比较目的操作数和 0)、jeq(标号零位被置时转移到标号语句)、add.w(源操作数加至目的操作数)、cmp.w(从目的操作数中减去源操作数方法是将源操作数求反再加 1)、jc(标号进位位被置时转移到标号语句)、inc.w(目的操作数加1)执行速度了 汇编我我就不懂了 。
网上查的430汇编指令表
MSP430指令速查表

指    令        操作数位置及执行过程        说    明        状 态 位
代 码        源操作数目的操作数        指令执行过程详述        VNZC
ADC[.W]或ADC.B        dst dst+C->dst        进位C 加至目的操作数 目的操作数以前的内容丢失        ****
ADD[.W]或ADD.B        src,dst src+dst->dst        源操作数加至目的操作数源操作数不受影响目的操作数以前的内容丢失        ****
ADDC[.W]或ADDC.B        src,dst src+dst+C->dst        源操作数和进位C 加至目的操作数源操作数不受影响目的操作数以前的内容丢失        ****
AND[.W]或AND.B        src,dst src.and.dst->dst        源操作数和目的操作数逻辑与结果放入目的操作        0***
BIC[.W]或BIC.B        src,dst not.src.and.dst->dst        求反后的源操作数和目的操作数逻辑与结果放入目的操作数源操作数不变        ----
BIS[.W]或BIS.B        src,dst src.or.dst->dst        源操作数和目的操作数逻辑或 结果放入目的操作数 源操作数不变        ----
BIT[.W]或BIT.B        src,dst src.and.dst        源操作数和目的操作数逻辑与其结果只影响状态位目的操作数和源操作数不变        0***
BR        dst转移到        无条件转移到64K 地址空间的任一地址处可使用所有的源寻址方式转换指令是一个字指令        ----
CALL        dstPC+2->堆栈,dst->PC        调用64K 地址空间中任一地址处的子程序可使用所有的寻址方式返回地址(后续指令的地址)储存在堆栈中调用指令是一个字指令        ----
CLR[.W]或CLR.B        dst清除目的操作数        清除目的操作数        ----
CLRC        清除进位位        进位位被清零清除进位位指令是一个字指令        ---0
CLRN        清除负位        常数#04H 求反后(0FFFBH)和目的操作数逻辑与结果放入目的操作数清除负位指令是一个字指令        -0--
CLRZ        清除零位        常数#02H 求反后(0FFFDH)和目的操作数逻辑与结果放入目的操作数清除负位指令是一个字指令        --0-
CMP[.W]或CMP.B        dstdst-src        从目的操作数中减去源操作数方法是将源操作数求反再加 1,源操作数和目的操作数不受影响不保存结果只影响状态位        ****
DADC[.W]或DADC.B        dst dst+C->dst(十进制)        进位位C 作为十进制加至目的操作数        ****
DADD[.W]或DADD.B        src,dst src+dst+C->dst(十进制)        源操作数和目的操作数被当作4 个带有正符号的二-十进制BCD 数十进制的源操作数和进位C 被加至目的操作数源操作数不受影响目的操作数以前的内容丢失些结果对于非二-十进制数是不确定的        ****
DEC[.W]或DEC.B        dst dst-1->dst        目的操作数减1 以前的内容丢失        ****
DECD[.W]或DECD.B        dst dst-2->dst        目的操作数减2 以前的内容丢失        ****
DINT        禁止中断        禁止所有中断        ----
EINT        使能中断        使能所有中断,常数08H 与状态寄存器SR 逻辑或其结果放入SR        ----
INC[.W]或INC.B        dst dst+1->dst目的操作数增1        目的操作数加1 以前的内容丢失        ****
INCD[.W]或INCD.B        dst dst+2->dst目的操作数增2        目的操作数加2 以前的内容丢失        ****
INV[.W]或INV.B        dst目的操作数求反        目的操作数取反以前的内容丢失        ****
JC/JHS        标号进位位被置时转移到标号语句        测试状态寄存器的进位位C 如果它被置则指令的LSB 中包含的10 位符号偏移加至程序计数器如果C 被复位则执行JUMP 后面的一条指令JC( 有进位/大于等于时跳转 )用于比较无符号数(0~65536)        ----
JEQ/JZ        标号零位被置时转移到标号语句        测试状态寄存器的零位Z 如果它被置则指令的LSB 中包含的10 位符号偏移加至程序计数器如果Z 被复位则执行JUMP 后面的一条指令        ----
JGE        标号N.xor.V=0时转移到标号语句        测试状态寄存器的负位N 和溢出位V 如果N 和V 均被置位或复位则指令的LSB 中包含的10 位符号偏移加至程序计数器如果其中之一被置位则执行JUMP 后面的一条指令该指令允许比较符号整数        ----
JL        标号N.xor.V=0时转移到标号语句        测试状态寄存器的负位N 和溢出位V 如果N 和V 其中之一被置位则指令的LSB 中包含的10 位符号偏移加至程序计数器如果两都均被置位或复位则执行JUMP 后面的一条指令该指令允许比较符号整数        ----
JMP        标号无条件转移到标号语句        指令的LSB中包含的10 位符号偏移加至程序计数器        ----
JN        标号负位被置时转移到标号语句        测试状态寄存器的负位N 如果N 被置位则指令的LSB 中包含的10 位符号偏移加至程序计数器如果N 被复位则执行JUMP 后面的一条指令该指令允许比较符号整数状态位 不影响状态位        ----
JNC/JLO        标号进位位复位时转移到标号语句        测试状态寄存器的进位位C 如果它被复位则指令的LSB 中包含的10 位符号偏移加至程序计数器如果C 被置位则执行JUMP 后面的一条指令JC( 有进位/大于等于时跳转 )用于比较无符号数(0~65536)        ----
JNE/JNZ        标号零位复位时转移到标号语句        测试状态寄存器的零位Z 如果它被复位则指令的LSB 中包含的10 位符号偏移加至程序计数器如果Z 被复位则执行JUMP 后面的一条指令        ----
MOV[.W]或MOV.B        src,dst src->dst        源操作数被移至目的操作数源操作数不变 目的操作数以前的内容丢失        ----
NOP        空操作        此指令可用于在检查软件期间 仿真指令或用于已确定的等待时间        ----
POP[.W]或POP.B        dst项目从堆栈弹出,SP+2->SP        堆栈指针(TOS)指向的栈区字移至目的操作数随后堆栈指针加2        ----
PUSH[.W]或PUSH.B        src SP–2->SP,src->@SP        堆栈指针减2 然后源操作数移至由此指针(TOS)寻址的RAM 字        ----
RETI        TOS->SR SP+2->SP,TOS->PC SP+2->SP        (1)状态寄存器恢复到中断服务程序开始时的值用TOS 存储器中的值替换SR 中的当前值可做到这一点堆栈指针SP加2
(2)程序计数器恢复到中断服务程序开始时的值这是中断程序流的后续步骤用TOS 存储器中的值替换PC 的当前值可实现这种恢复堆栈指SP 加1        ----
RET        TOS->SR SP+2->SP        由CALL 指令压进栈的返回地址移至程序计数器程序在子程序调用后的代码地址处继续执行        ----
RLA[.W]或RLA.B        dst算术左移        目的操作数左移一位MSB成为进位位C LSB 填0 RLA 指令可当作符号乘2 在执行该操作前如果dst 大于等于04000H 且小于0C000H 则产生溢出结果会改变符号        ****
RLC[.W]或RLC.B        dst带进位位左移        目的操作数左移一位进位位C 移入LSB MSB移入进位位C        ****
RRA[.W]或RRA.B        dst算术右移        目的操作数右移一位MSB移入MSB MSB移入MSB – 1 LSB + 1 移入LSB        0***
RRC[.W]或RRC.B        dst带进位位右移        目的操作数右移一位进位位C 移入MSB LSB移入进位位C        ****
SBC[.W]或SBC.B        dst从目的操作数减去借位        进位C 加到减1 后的目的操作数目的操作数原来的内容丢失        ****
SETC        置进位位        进位C 被置这是一个常用的操作        ---1
SETN        置负位-1        负位N 被置        -1--
SETZ        置零位-1        负位Z 被置        --1-
SUB[.W]或SUB.B        src,dst dst+.not.src+1->dst        从目的操作数中减去源操作数方法是将源操作数求反再加上常数1 源操作数不受影响目的操作数以前的内容丢失        ****
SUBC[.W]或SUBC.B        src,dst dst+.not.src+C->dst        从目的操作数中减去源操作数方法是将源操作数求反再加上进位C 源操作数不受影响目的操作数以前的内容丢失        ****
SWAP        dst交换字节        目的操作数的高位字节和低位字节互换        ----
SXT        dst dst位7->位8......位150        低位字节的符号扩展到高位字节        0***
TST[.W]或TST.B        dst测试目的操作数        比较目的操作数和 0 根据结果设置状态位目的操作数不受影响        0**1
XOR[.W]或XOR.B        src,dst src.xor.dst->dst        源操作数和目的操作数异或其结果放放目的操作数源操作数不受影响        ****
注:
1、以上指令共51条
2、状态位中“*”表示影响“-”表示不影响“0”表示清零“1”表示置位
3、含.B的为单字节操作指令,含[.W]的为双字节操作指令(可省略)
4、src 源操作数,dst目的操作数,TOS堆栈顶部,SR状态寄存器,SP堆栈指针

292302877 发表于 2012-1-6 20:09:48

讲解得深刻,不过用汇编的时候都没有这么去关注每一条指令啊……

sunshulin 发表于 2012-1-6 20:14:00

回复【1楼】292302877
讲解得深刻,不过用汇编的时候都没有这么去关注每一条指令啊……
-----------------------------------------------------------------------

可能差别太小了就忽略   如果要是注重功耗和速度的 应该考虑一下

voval 发表于 2012-1-6 21:20:13

见过别人这么用

cd4514 发表于 2012-1-9 08:54:12

make

1049667 发表于 2012-1-9 10:13:08

细活啊。。

zhengdahe 发表于 2012-1-9 10:40:11

mark

gmyu 发表于 2012-1-9 11:29:58

值得研究--++

ubuntuman 发表于 2012-1-9 12:49:04

mark

mingyuexin1981 发表于 2012-1-9 13:13:54

其实,用这个
n = 240

do
{
   //-----------------

}while(--n)

在51汇编就是DJNZ

ayumi8 发表于 2012-1-9 13:45:55

我是新手 之前看过坛子里的文章   -- 是比++快啊

34071417 发表于 2012-1-12 14:12:10

延时功能用的话,却是没什么好说的,但是for循环内部实现功能就不好说

wadz365 发表于 2012-2-3 10:55:01

好像--编译后的汇编语句条数会少一点,执行时间短,功耗就小一点了,用430,不过没这么仔细的抠过

yzm158 发表于 2012-2-17 13:02:16

谢谢分享。新手受教了
页: [1]
查看完整版本: 关于430单片机的一点小发现 个人认为在榨压430单片机功耗这会有一点小用处