EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
如何编写高效率稳定的单片机代码
% x, [# `/ Z( E1 _6 o, W7 a! {# I+ Y% J
由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化: 使用尽量小的数据类型 " \0 Y! h) }0 v
能用unsiged就不用signed; . V7 Y. n- K" [- L
能用char就不用int;
- I# S- ?4 J) j7 w, n ^能不用floating就不用。
5 r8 C: U; K' B2 N+ y* O能用位操作不用算数。 使用自加、自减指令
" Z7 r) X/ A' V4 ]( m通常使用自加、自减指令和复合赋值表达式(如a-=1 及a+=1 等)都能够生成高质量的 / c2 G* @; k) W0 F1 t; c5 k
程序代码,编译器通常都能够生成inc 和dec 之类的指令,而使用a=a+1 或a=a-1 之类
4 C2 c: P9 X( Q# P" @! v# d) F% G的指令,有很多C 编译器都会生成二到三个字节的指令。 减少运算的强度
- v) f2 k- I- Q% R3 r: E. {可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。 : r9 q$ f9 y) n. ^
(1) 求余运算
) X/ R. R7 y3 C7 gN= N %8 可以改为N = N &7 ( g* g, E/ P5 _/ j& D# I4 M" [
说明:位操作只需一个指令周期即可完成,而大部分的C 编译器的“%”运算均是调用子程序来 6 y6 a! J0 f3 j2 K1 b
完成,代码长、执行速度慢。通常,只要求是求2n 方的余数,均可使用位操作的方法来代替。
( r5 c9 E# O3 K(2) 平方运算
; L0 x! r+ K) w* SN=Pow(3,2) 可以改为N=3*3 7 u" G5 O! q$ [) D9 d6 B
说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多, 因为浮点数 8 Y8 G) H* o% G
的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。 - E2 ?6 v1 ?6 Q2 Z9 a {3 ^- Y
(3) 用位移代替乘法除法
( @# s0 j/ M! s; M2 R+ O \' e( ?N=M*8 可以改为N=M<<3
* d1 p0 [8 U) UN=M/8 可以改为N=M>>3
0 [+ X2 S8 u) h1 o说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
$ B- b. Q8 K4 l' @& o, r的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子
/ Y1 P& E, s. d# |* H7 m3 m程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。
7 C) G1 ~# a" P# S. Y9 ^8 l! u7 @如N=M*9可以改为N=(M<<3)+M;
/ i3 z3 {5 X! P(4) 自加自减的区别
7 P( E0 S1 D) p; V' E: a9 |5 A4 {6 x例如我们平时使用的延时函数都是通过采用自加的方式来实现。 ; p; `- h* O1 f& ^
void DelayNms(UINT16 t)
) ~2 l4 y# p5 {/ B' C! F{
1 J5 D2 Z u1 n$ i4 a" y4 uUINT16 i,j;
8 X/ J \$ W* D6 d5 N5 qfor(i=0;i 0 t |& E+ [+ {7 b' @
define MAX(A,B) {(A)>(B)?(A) B)}* P2 `+ i% c1 G6 z- h# \, t. y
|