问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何写出高效的单片机C语言程序代码

发布网友 发布时间:2022-05-26 14:29

我来回答

1个回答

热心网友 时间:2023-10-22 02:41

由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法
与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。
对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片
机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须
遵循以下几点进行优化:

1. 使用尽量小的数据类型
能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变
量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变
量后不要超过变量的作用范围,如果超过变量的范围赋值,C 编译器并不报错,但程序运行结果却错了,
而且这样的错误很难发现。

2. 使用自加、自减指令
通常使用自加、自减指令和复合赋值表达式(如a-=1 及a+=1 等)都能够生成高质量的
程序代码,编译器通常都能够生成inc 和dec 之类的指令,而使用a=a+1 或a=a-1 之类
的指令,有很多C 编译器都会生成二到三个字节的指令。

3. 减少运算的强度
可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。
(1) 求余运算
N= N %8 可以改为N = N &7
说明:位操作只需一个指令周期即可完成,而大部分的C 编译器的“%”运算均是调用子程序来
完成,代码长、执行速度慢。通常,只要求是求2n 方的余数,均可使用位操作的方法来代替。
(2) 平方运算
N=Pow(3,2) 可以改为N=3*3
说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多, 因为浮点数
的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。
(3) 用位移代替乘法除法
N=M*8 可以改为N=M<<3
N=M/8 可以改为N=M>>3
说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子
程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。如N=M*9
可以改为N=(M<<3)+M;
(4) 自加自减的区别
例如我们平时使用的延时函数都是通过采用自加的方式来实现。
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=0;i<t;i++)
for(j=0;i<1000;j++)
}
可以改为
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=t;i>=0;i--)
for(j=1000;i>=0;j--)
}
说明:两个函数的延时效果相似,但几乎所有的C 编译对后一种函数生成的代码均比前一种代码少1~3
个字节,因为几乎所有的MCU 均有为0 转移的指令,采用后一种方式能够生成这类指令。

4. while 与do...while 的区别
void DelayNus(UINT16 t)
{
while(t--)
{
NOP();
}
}
可以改为
void DelayNus(UINT16 t)
{
do
{
NOP();
}while(--t)
}
说明:使用do…while 循环编译后生成的代码的长度短于while 循环。

5. register 关键字
void UARTPrintfString(INT8 *str)
{
while(*str && str)
{
UARTSendByte(*str++)
}
}
可以改为
void UARTPrintfString(INT8 *str)
{
register INT8 *pstr=str;
while(*pstr && pstr)
{
UARTSendByte(*pstr++)
}
}
说明:在声明局部变量的时候可以使用register 关键字。这就使得编译器把变量放入一个多用途的寄存
器中,而不是在堆栈中,合理使用这种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的
速度,注意register 关键字只是建议编译器而已。

6. volatile 关键字
volatile 总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在
哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等优化,进一步可以死代码消除。一般来
说,volatile 关键字只用在以下三种情况:
a) 中断服务函数中修改的供其它程序检测的变量需要加volatile(参考本书高级实验程序)
b) 多任务环境下各任务间共享的标志应该加volatile
c) 存储器映射的硬件寄存器通常也要加volatile 说明,因为每次对它的读写都可能由不同意义
总之,volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素
更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码
就不再进行优化,从而可以提供对特殊地址的稳定访问。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
分形有什么 江苏省教育科学"十二五"规划课题经费是多少 全国教育科学"十二五"规划教育部规划课题有用吗 全国教育科学"十二五"规划是教育基础课题吗 ...女人,但是他表面对我很好,我抓不住他任何证据,这难道是我太闲了想... 总是怀疑老公对别的女人好怎么? 为什么日久生情的通常是女人? 为什么日久生情在女性中更为常见? 什么是日久生情?女生容易日久生情吗? 为什么日久生情的人多是女性呢? c语言这个题怎么写代码? 公司名称翻译成比较正规的英文格式,在线等,谢谢! 何谓光合作用? 光合作用公式:___+水 光能 有机物+__ 光合作用的公式是什么,,原料是什么 怎么把手提电脑话筒声音关掉 种草莓赚钱吗 传记的4种特点是甚么??? 情商之父 戈德曼 有什么书 帮忙写一篇《鲁滨逊漂流》读后感 ,600字以上 《情商》最新txt全集下载 从前的反义词的形容词 钢结构厂房优点有哪些 钢结构建筑的好处 钢结构的建筑有什么好处? wow英雄18波什么意思?怎么才能去 魔兽世界18M 中的问题 魔兽世界英雄18M是什么本?全名叫什么 魔兽世界18m问题! 魔兽世界YX18M是什么任务啊 中央空调 美的好吗?听说美的做很多年了,懂得说一下 谢谢! 公务员面试时,考官一般是由什么人组成呢。他们在面试前真的看过我们的简历对我们有初步了解吗?不是都是 电脑过一会没动,就会自动弹出风行网的电影广告,全屏的。。怎么去掉啊?? 用人单位会通过核对档案来看看我的应聘简历是否属实吗? 中职学校类的事业单位面试一般要问什么 测量0-10MPa用的精密压力表 会计学不会怎么办 如何看压力表? 对会计不感兴趣,大学四年学不好会计怎么办 上学年大一会计没学好,现在想自学,把落下的都补起来,我不想比别人差 我是学会计的,但学得不好,想找一分会计或出纳的工作怎么办? 同仁堂的瓶装冰糖燕窝怎么加热 明年就要实习了,学会计,可是实在是学的不好,证书也考不上,看到那些就头疼,不知道以后该怎么办,很迷 我是零基础 想学会计 但记性不好 看书老记不住怎么办 冰糖燕窝加苹果煮着吃可以吗? 会计专业学得不好出去社会该怎么办 冰糖燕窝能不能吃? 自己会计专业 可是却总是学不好,以后找工作怎么办? 燕窝是大热的吗?吃燕窝有什么好处? 我的会计学不好。用什么办法能学好啊?