本帖最后由 dffzh 于 2025-5-20 17:08 编辑
#申请原创#
@21小跑堂
做嵌入式产品的软件开发时,我们会经常遇到因为成本、交期或芯片资源紧张等原因更换MCU平台的情况,加上不同MCU厂商在芯片外设、寄存器和库函数接口等方面的命名规则和名称不一样,软件上肯定是避免不了要重新搭建和开发调试;这个时候,如果你的与MCU平台相关的底层驱动代码的复用率高,那你的开发工作量就会大大减少了。 下面作者就以实际开发案例与大家分享一下怎么样设计驱动代码以提高代码复用率,主要是针对MCU基于外围芯片的驱动代码与MCU配置相关的阐述,供大家参考和使用。 项目上用到了IS3980S芯片和U74HC595芯片,前者是输入:读取数字输入状态,后者是输出:驱动LED显示。 MCU和IS3980S芯片之间有如下4根信号线连接通信:
那在设计IS3980S的驱动代码时,这几根信号线就是实现为MCU的GPIO的定义和配置; 在通过GPIO口读写数据时,怎么样设计可以更方便代码以后的维护呢? 在C语言中,我们可以用宏定义#define的方式来实现GPIO口的绑定以及用宏函数实现GPIO的数据读写,相关代码如下所示,定义在is3980s.h头文件里面:
虽然这个项目里几个信号线引脚都是绑定在GPIOB,但为什么没有用IS3980S_GPIO,而要对每个信号线引脚单独加个宏定义来指向GPIO呢?这样设计的话,如果后续硬件更改了GPIO口,每个信号线引脚你只需要修改一个地方即可,方便快捷安全。如果MCU使用的引脚很多,不要觉得这种方式繁琐,反而更要用这种方式实现,后续维护时,你会很轻松,哪怕换了MCU平台,你一般只需要修改头文件里对应的宏定义名称即可,驱动代码源文件is3980s.c则不需要做任何更改。源文件里的函数实现举例如下:
总之一句话: 你的芯片驱动代码源文件里尽量不要直接使用MCU平台底层的东西,改用宏定义等方法来封装到头文件里; 宏定义功能越具体越详细,后续代码维护就越方便越简单,出现Bug的可能性就越低。
再举个例子,加深大家的印象: MCU和U74HC595芯片之间有如下4根信号线连接通信:
同样地,我们依葫芦画瓢,在u74hc595.h文件里就可以按如下代码定义这几个信号线引脚:
源文件里的一个函数实现如下:
这样,无论后续更换了什么MCU平台,你要做的工作就是把头文件里的相关宏定义更改一下即可,除非是什么比较奇葩的MCU平台,那另当别论了。
通过以上这种提高芯片驱动代码复用率的方法,无论是在代码修改量方面,还是在解决MCU平台移植和编译时报错问题多方面,或者是代码可读性和可维护性等方面,你将会深深受益,不信的话,你可以试试!
|