EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
如何编写高效率稳定的单片机代码4 Q% u1 \- C* j4 T3 k- y4 \' R
$ Y6 ^( x( [) ~6 }0 S! f* c! l
由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化: 使用尽量小的数据类型
( C! x, A, P2 M( C5 W- [能用unsiged就不用signed; , r5 V3 {6 K; R' ]* C
能用char就不用int; 4 P% c& f) {8 F5 }
能不用floating就不用。
, I+ o. o8 @4 M& |' L i能用位操作不用算数。 使用自加、自减指令 & M9 b: ]: j& P1 ~5 B$ C Y/ K
通常使用自加、自减指令和复合赋值表达式(如a-=1 及a+=1 等)都能够生成高质量的 3 W- H" I2 I7 d7 \5 E4 E) y9 b4 n
程序代码,编译器通常都能够生成inc 和dec 之类的指令,而使用a=a+1 或a=a-1 之类
7 A/ P& r) R- j8 ~7 F: |的指令,有很多C 编译器都会生成二到三个字节的指令。 减少运算的强度 ( R% q" Q- C! ~1 n- c/ D5 h
可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。 ! M, ^ Y, f7 u4 i5 W
(1) 求余运算
' f* I6 e8 h6 X" D2 fN= N %8 可以改为N = N &7
- R* I" `# k5 H; x说明:位操作只需一个指令周期即可完成,而大部分的C 编译器的“%”运算均是调用子程序来 2 ^/ z6 `2 L7 D/ M" t6 r) C# t' @
完成,代码长、执行速度慢。通常,只要求是求2n 方的余数,均可使用位操作的方法来代替。 6 C; ?* a. ]0 M
(2) 平方运算
7 l) Q: e$ V4 E( t0 C" m0 eN=Pow(3,2) 可以改为N=3*3 ; k8 h- f: H I
说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多, 因为浮点数 ( _* u8 D/ S. v0 d
的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。
' k7 ? w3 {0 v: \6 L1 N, T(3) 用位移代替乘法除法 # `3 F7 B. I' S4 f" N
N=M*8 可以改为N=M<<3
- C+ m% s# L' ^ x) j( XN=M/8 可以改为N=M>>3 I M7 Z- ]1 s/ j/ [
说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
, v+ P) q( B2 Z8 z/ X3 x的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子 ( Q p! r0 [& H8 z/ O7 c
程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。
" Z+ h T @) ?' h/ s9 q如N=M*9可以改为N=(M<<3)+M; : }' f& u( |1 f0 T9 o9 c q* \
(4) 自加自减的区别
* _ q1 _$ C5 W( |例如我们平时使用的延时函数都是通过采用自加的方式来实现。
. J' Q, K" `: B5 Evoid DelayNms(UINT16 t) 7 w" L- \# d5 u# T( U
{ ' f. c1 b" E2 Y; N+ D
UINT16 i,j;
& |6 Z5 X+ T) K& | K" Y- Q( K3 ^$ s& pfor(i=0;i
$ e: Y: r v5 Y- m define MAX(A,B) {(A)>(B)?(A) B)}
: V V( _* s; N2 B9 B6 u ^ |