单片机开发项目全局变量太多怎么管理?
大家好,我是无际。
最近有几个小伙伴反映说自己写程序感觉很乱,不知道怎么去规划,想到什么就写什么,全局变量满天飞,代码一多就出现好多问题。
而且如果自己写的程序不加注释的话,过几个月发现看不懂了。
一个工程师的成长过程,总是惊人地相似,曾经我也和大家一样,一直想解决程序如何写能更好这个问题。
全局变量太多难管理,看起来是个小问题,要想解决其实背后涉及很多东西,否则不如你直接加注释来得更直接。
变量确实要用,你省不了,你只能通过别的方式去规避乱的问题,比如说一些编程技巧和思维 。
后面经过无数项目洗礼,我个人领悟是:一个程序写得好不好,主要看程序算法 和程序架构 。
先来说说算法好了, 算法不是刚需。
很多新手以为程序要想写得好,跟英语和数学水平有关系。
今天我给大家交个底,并不是,最多数学好算法能做得更优,大多数产品算法都不复杂,单片机能做多复杂的运算是吧?
很多算法,难在前端公式剖析,不管再复杂的项目都好,最后体现在程序里的都是加减乘除,与或等这些简单运算。
举个例子:
请给出能够计算出结果等于8的公式。
不同的人,计算出来的公式可能是不一样的,比如以下几种公式都能实现。
公式1: (1+1)*(2+2);
公式2: 1<<3
很明显,公式2 的计算效率更高,主要是体现在汇编指令更少,机器周期自然更短,所以说算法更好。
实际上真正的算法比这个要复杂得多,这里只是举个例子而已。
像这种公式,一般我们在小笔记本上先算好,最后转成用加减乘除之类的公式用程序写出来。
大多数情况,只要产品实时性要求不是特别苛刻的,公式1和公式2你看不出任何区别。
并不是每个行业的产品都需要算法,每个行业的算法肯定也是不一样。
哪怕你数学很差,都没关系,你找个数学厉害的人,告诉他你要算什么。
让他用加减乘除、与、或、移位运算帮你算出一个最佳解题公式,你带入到程序直接用就行了。
所以我们在做产品的时候,不要过度去追求程序执行效率,只要能满足需求就好,并不是刚需。
研究算法是很浪费时间的,通用性也不强,反正就是性价比很低。
下面再来说说程序架构 ,这个实用性 和通用性极强 。
而且可以说不懂架构中大型项目绝对做不来,不是做不好,而是做不来!
可能很多人工程师做了几年,已经碰到了瓶颈期,一直想提升,又无能为力。
比如说,变量多了,函数多了,程序总是乱糟糟的,一整合起来一堆BUG。
这个功能好了,影响了别的功能,改了别的功能,这个功能又不行了。
最后马马虎虎把代码好不容易整合起来实现完整的产品功能了,也没BUG了。
挨千刀的老板又跟你说要改功能,在刚开始做研发那几年,我就最怕增加功能、改功能。
哪怕只是把LED改成每秒闪1次,又或者说增加一个按键这么小的功能,如果架构不好的话,都有可能花上你一周甚至更长。
那程序架构到底是什么?
我认为是一种成熟的编程思维,是经验的总结,比如RTOS就是属于一种程序架构,STM32固件库也是一种程序架构。
不同的人,编写出来的程序架构都不一样,有大的有小的,最重要是够用就好 。
而全局变量多导致程序乱的问题,就可以用程序架构的模块化编程特点来解决。
具体怎么做?
1.以不同的层次不同的文件区分
一般在写STM32级别项目,我都会分为两层:硬件层 和应用层 。
硬件层 主要负责单片机的相关外设配置和一些功能驱动。
拿我们无际单片机编程的wifi报警主机项目来举例。
硬件层 有临界管理、喇叭PWM驱动、EEPROM存储、按键检测、LED特效功能、OLED屏驱动、无线数据软解码、定时器矩阵、串口数据收发这些功能。
每个功能都是单独的.c和.h文件,这样更好区分和管理各个不同功能模块代码。
如果把这些都写在一个.c文件里,那涉及的函数和全局变量非常多,很混乱,查找也不方便。
2.我一般会把不同功能模块的全局变量、数组定义到对应的.c文件里。
这样定义以后,只要你不搞extern声明,别的.c文件基本是访问不了你这些变量或数组的,一定程度上起到保护的作用。
还有一点就是,如果你在不同的.c文件定义了同一个变量名,编译器一般也会报错。
还有一种方法,可以解决这种可重名问题,就是用static关键词。
这样就明确告诉编译器,我这些数组的作用域仅限于该.c文件,变量也是一样的道理,这样修饰以后你在别的.c文件也可以定义名字一样的变量,两个是相互独立的。
还有一个很重要的细节就是,对于那些不需要给外部调用的函数,我都用static关键词修饰。
这样可以增强可读性,方便后期维护,你一看就知道哪些函数是本文件内使用,哪些是外部的接口。
单片机为什么用全局变量比较多
想学习单片机的同学可以关注、私信我或者在评论区回复我要入门。我们使用C语言开发单片机时比较多的使用的是全局变量的形式,主要的原因有以下几点:
使用全局变量在单片机开发是一种比较方便的形式,很多数据理论上是可以保存在栈中的,那就要求开发者对栈的机制非常的熟悉,栈溢出是一个让开发者非常头疼的一个问题,因为出错的地方查找起来非常的困难,所以尽量不要在函数内部定义大数组,同理堆的malloc内存碎片和申请失败问题,也一样难以分析,因此大数组定义成全局变量会让我们省心省力。
不合理的全局变量,如零散的全局变量会让后期的维护比较的困难,但如果设计合理,将有关联的功能组合成结构体声明,注释相关功能,那后期维护起来就非常的方便。
全局变量引入的不可重入和多任务的同步问题,可以通过开关中断和互斥量来处理,我个人觉得不会影响实际的应用。
至于容量,性能问题都是细枝末节,栈变量不会比全局变量区慢,内存占用设计得合理的情况下,理论上栈变量的复用性更高,会占用更少,但需要花费时间去解决使用栈引入的问题,每个人的使用习惯不一样,反正我是不会这样做的。
如果是这种情况,一个变量只会被a修改,b使用的情况,那么是不应该用全局变量的,然而实际应用中,变量可能会被a,b,c, d等多个函数修改和使用,如果不使用全局变量,使用变量的函数接口都要添加相应的变量指针,在后期需求需要修改时,理论上会更难以维护。
本期先分享到这里,想要进群学习单片机编程的同学可以私信我,回复“我要入门”,与我们一起成长,喜欢的可以点个赞关注我们!结合这些因素综合来看,合理的使用全局变量对开发是非常有利,既然有利自然被项目所采用,而需要避免的是滥用的情况。
相关问答
单片机 怎么定义 全局 数组?在单片机中定义全局数组需要在程序的开头或者全局变量区域声明数组变量,并指定数组的数据类型和大小。全局数组可以在程序的任何位置被调用和修改,它的作用域...
单片机变量 由什么组成?单片机的变量主要由两个部分构成:一个是变量名,一个是变量值。每个变量都有一个变量名,AD7656BSTZ-1在内存中占有一定的内存单元(地址),并在该内存单元中...
单片机 中怎么声明位 变量 ?就是仅有一位的 变量 那种,是bita吗?是的,对于C51单片机来说,以下有以下类型变量:bita1位unsignedchara,或者chara8位unsignedshorta或者shorta16位unsignedlonga或者lon...
单片机 c51有哪些 变量 ,谢谢?跟标准c是一样的,有charshortintfloatdoubleunsignedcharunsignedshortunsignedint跟标准c是一样的,有charshort...
STC89C52 单片机 里头可以定义多少个位 变量 (也就是bit型的)我...如果想用200个位变量的话,完全可以先定义字节变量,然后对字节里的位进行处理,也很方便。STC89C52单片机只有128位位寻址空间你使用xdata进行定义吧,可以定义...
单片机 中怎么声明位 变量 ?就是仅有一位的 变量 那种,是bit a吗?是的,对于C51单片机来说,以下有以下类型变量:bita1位unsignedchara,或者chara8位unsignedshorta或者shorta16位unsignedlonga或者longa32...
单片机 lcd怎么同时显示两个 变量 ?那就是个整流桥堆,说白了相当于里面有4个整流二极管。并联104电容用于针对高频信号滤波,提升电源纯净度。那就是个整流桥堆,说白了相当于里面有4个整流二极管...
8位 单片机 如何定义32位 变量 ?可以在头文件中定义一个地址连续的4字节变量,这就构成了32位变量。为了保险起见,这个变量需要定义成全局变量,可能会被逻辑运算的其它局部变量占用,导致运算...
想问一下用汇编语言写 单片机 程序时,怎么定义一个数组 变量 ?严格的说,汇编语言不支持显式数组变量,就是说你想定义一个任意数组,然后用下标访问是不行的。但汇编语言支持隐式数组变量,其实就是对变量表间接寻址,使用...
2. 单片机 内部RAM可分为几个区?各区的主要作用是什么?内部RAM一共三个区,第一区:低128字节(物理地址是00H---7FH),C语言用data修饰,特点是直接寻址,寻址速度最快,在实际应用中,频繁使用的变量最好定义到这个区,因...