EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
如何编写高效率稳定的单片机代码7 J# F; l* Q5 | R% z7 v
+ B5 w* l7 H7 s9 z5 r$ Z由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化: 使用尽量小的数据类型 + M3 D4 `# d; O& \% P6 w6 H: x0 c
能用unsiged就不用signed; + x6 C- A* X5 n! T+ R( z0 L& C5 v
能用char就不用int;
8 ?' U/ P8 E- }2 v* |能不用floating就不用。 5 A- ]' P) G" L; w
能用位操作不用算数。 使用自加、自减指令
# |5 B7 M! L+ L4 n. Q \& `通常使用自加、自减指令和复合赋值表达式(如a-=1 及a+=1 等)都能够生成高质量的
- f' J$ s1 {+ d" e4 m, U+ V& C# I程序代码,编译器通常都能够生成inc 和dec 之类的指令,而使用a=a+1 或a=a-1 之类
) b/ {9 J( k9 w# s# p# Q% h. N( a4 B3 I的指令,有很多C 编译器都会生成二到三个字节的指令。 减少运算的强度 + P' E9 o! W6 N- @- |
可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。
. N7 i) q+ s6 U+ v& U& @(1) 求余运算
5 M8 @% Q/ }) C6 L1 \$ ?% r! {N= N %8 可以改为N = N &7
7 T) D' U* j/ {" K& V9 ~说明:位操作只需一个指令周期即可完成,而大部分的C 编译器的“%”运算均是调用子程序来 8 y" R l2 ^: L4 \# G0 ]3 P
完成,代码长、执行速度慢。通常,只要求是求2n 方的余数,均可使用位操作的方法来代替。 & F- D& |& I5 o/ z
(2) 平方运算 + k3 ?2 R! Y3 W+ [8 J* @0 H
N=Pow(3,2) 可以改为N=3*3 / q& N2 C5 e R: D6 T, F
说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多, 因为浮点数 & u6 c+ u4 @7 m2 `8 o# h* \3 w
的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。
2 M; Y* s5 a7 u. q) \; y( o(3) 用位移代替乘法除法
* u; \7 h0 g4 KN=M*8 可以改为N=M<<3
4 Y% X; D+ O3 i7 h( E! N( oN=M/8 可以改为N=M>>3 ! N# @+ i( w7 r* ?* y- s
说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
2 c3 {( I& i9 {; G: d' c, g的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子
: z; P9 Y7 y3 b5 H5 Y" G- v a' N' i程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。
* g p9 t. A" P N7 s5 C. ]$ L如N=M*9可以改为N=(M<<3)+M; % e5 u( m" s9 I6 z7 g
(4) 自加自减的区别
6 l0 y) P8 b! P. j; B' E$ Q例如我们平时使用的延时函数都是通过采用自加的方式来实现。 h& i% |' h# h! X0 z6 `
void DelayNms(UINT16 t)
+ d& _1 t' I2 \0 `+ r( I& h( F* x{ 4 k6 P& _- J; F- g) {7 q7 ^6 W
UINT16 i,j; 6 I& M/ g: d& Y1 z6 J
for(i=0;i
) }/ y- ?- q5 ~8 `" c$ W6 Q define MAX(A,B) {(A)>(B)?(A) B)}
/ H0 I2 e' I/ s' Q( u" E b' k |