如何编写高效的单片机代码?

ops/2024/9/23 12:29:07/

单片机的程序比软开少一些,真正想编写出高效的代码,还是要积累很多年的。

在做研发工程师的10年里,我经历过几个公司,看过很多工程师写的代码,但真正能让我跪着看完的,极少。哪怕是大厂工程师,也会有让人笑掉大牙的代码。

高效的背后,有很多学问,需要有一定的数学功底,对编译器有较深的了解,懂汇编

具备这些能力,写出来的代码,才能让cpu执行这段代码所花费的时间,以及占用的ROM和RAM资源更少。

然而,如果把项目每个细节,都优化到高效的程度,花费的时间,是平时的两倍。

所以,我们在做项目时,一般只优化核心功能,才能赶上项目的进度,除非经验相当丰富。

下面分享几点高效代码的技巧:

1.使用位操作代替算术操作,因为位操作更快。

还有就是用左移、右移替代乘除法。

比如a=b*256,可以改成a = b<<8

比如a=b/256,可以改成a = b>>8

2.避免不必要的操作

去除代码中不必要的操作,如多余的变量赋值、函数调用等。

3.控制数据类型大小

特别是尽量别用float,浮点运算通常需要更多的CPU周期和内存空间,因为浮点数的表示和运算比整数复杂,除非单片机内置了硬件浮点单元(FPU)。

能用unsigned就不用signed,无符号整数的运算可能比有符号整数更快,因为不需要处理符号位。

能用char就不用int,较小的数据类型在处理和传输时更快,因为它们占用的内存和带宽更少。特别对于存储大量数据的数组或缓冲区,使用 char 类型可以显著减少内存占用。

4.利用硬件资源

比如说STM32单片机,可以利用DMA传输数据,减少CPU负载。

5.代码重用

一些重复的代码,通过函数或宏来重用代码。

6.自加、自减指令

用i--、i-=1、i++、i+=1、去替代i = i-1,i=i+1的操作,有些编译器对前者进行了优化,效率更高。

7.优化算法

以计算1到100的和为例。

我们可能会首先想到使用循环,来写程序:

这种方法虽然直观,但在效率上可能不是最优的。

那怎么去优化?

这时候就要考验工程师的数学功底了。

可以根据等差数列求和公式,1到100的和可以表示为:

n是序列的最后一项,即100。将这个公式应用到代码中:

对以上两种实现代码的总结:

尽管程序都能得到相同的结果,但是第二种方法在运行效率上明显优于第一种。因为它避免了循环的开销,直接通过数学公式计算出结果。

在编写单片机代码时,尽量通过数学方法,或其他算法技巧,提高程序的执行效率。

这不仅可以减少了CPU的计算时间,还能减少程序占用的内存空间,从而提高整体性能。

插个题外话,之前很多老铁问我,数学不好,可以学单片机吗?

我觉得这就是一个很好的例子,数学不是门槛,而是天花板。

第一种实现方式,是小学算数低,但效率低。

第二种,则需要一定的数学能力,但效率高。

那同样都能实现功能,效率低点就低点呗,有什么所谓?

其实这个会间接影响到硬件成本。

比如数学功底好的,可以用低端单片机去实现功能,而数学功底不好的,写出来代码效率低,则需要性能更强的单片机支撑。

不过,很多产品,对效率的要求并没这么苛刻,哪怕用第一种方式,照样没问题。


http://www.ppmy.cn/ops/44881.html

相关文章

端口扫描利器--nmap

目录 普通扫描 几种指定目标的方法 TCP/UDP扫描 端口服务扫描 综合扫描 普通扫描 基于端口连接并响应(真实) ​ nmap -sn 网段(0/24)-sn 几种指定目标的方法 单个IP扫描 IP范围扫描 扫描文件里的IP 扫描网段,(排除某IP) 扫描网段(排除某清单IP) TCP/UDP扫描 -sS …

重学java51.Collections集合工具类、泛型

"我已不在地坛&#xff0c;地坛在我" —— 《想念地坛》 24.5.28 一、Collections集合工具类 1.概述:集合工具类 2.特点: a.构造私有 b.方法都是静态的 3.使用:类名直接调用 4.方法: static <T> boolean addAll(collection<? super T>c,T... el…

Spark

from pyspark import SparkConf, SparkContext def MyPartitioner(key): print(“MyPartitioner is running”) print(‘The key is %d’ % key) return key%10 def main(): print(“The main function is running”) conf SparkConf().setMaster(“local”).setAppNa…

62、 忠北国立大学计算机科学系:FingerNet-专门用于细致MI分类的神经网络模型

本文由泡菜国高校于2024年3月6日发表于arXiv&#xff0c;做了一个专门处理运动想象信号的CNN模型&#xff0c;融合了EEGNet和DeepConvNet。 FingerNet是一种专门用于细致MI分类的网络&#xff0c;利用了时间特征&#xff0c;在相同手部分类任务中表现出比EEGNet和DeepConvNet更…

PYQT5点击Button执行多次问题解决方案(亲测)

PYQT5点击Button却执行多次问题 使用pyqt5时遇到问题&#xff0c;UI上按钮点击一次&#xff0c;对应的槽函数却执行了3遍 首先&#xff0c;确认函数名无冲突&#xff0c;UI button名无命名冲突&#xff0c;下图是简单的示例程序&#xff1a; 运行后&#xff0c;点击按钮&#…

Element-UI 入门指南:从安装到自定义主题的详细教程

Element-UI 是一个基于 Vue.js 的前端组件库&#xff0c;它提供了丰富的 UI 组件&#xff0c;可以帮助开发者快速构建高质量的用户界面。以下是使用 Element-UI 的快速入门指南&#xff1a; 安装 Element-UI Element-UI 是一个基于 Vue.js 的组件库&#xff0c;它提供了丰富的…

第8章 原生MVC服务框架一

1 组件化重构 1.1 分而治之 分而治之(Divide and Conquer)是一种软件设计原则,它的核心思想是将大问题分解成小问题,以便更容易地解决。 具体而言,该原则建议将复杂的软件系统分解成更小、更易于管理的模块。每个模块都应该具有清晰的目标和职责,以便更容易理解、测试和…

Java中的JDBC是什么?如何使用它连接数据库?

一、技术难点 JDBC&#xff08;Java Database Connectivity&#xff09;是Java语言与数据库之间进行交互的API。它允许Java程序通过SQL&#xff08;结构化查询语言&#xff09;来执行各种数据库操作&#xff0c;如查询、更新、删除等。然而&#xff0c;使用JDBC也存在一些技术…