0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何写出稳定的单片机代码

无际单片机编程 来源:无际单片机编程 2024-11-15 16:40 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

这篇文章分享怎么写出稳定的单片机代码。

我对优秀代码的理解,大体分为两个部分:高效和稳定。 两者都能做到很好的,如果靠自己摸索,没有刻意去练习,可能需要花10年,甚至更久。

对于单片机产品来说,高效可能不是刚需。

高效写法和低效写法,在很多功能上看不出区别,代码执行效率快个纳秒、微秒、甚至是毫秒的时间差,对功能本身并无影响。

所以在高效和稳定之间,我建议先提升怎么把程序写稳定,再进一步优化程序效率。

如果当下觉得自己写的代码比较烂,也没关系,先多写,再多学习高手写的代码,你就能看出其中的精华。

经验不足的时候,哪怕别人直接给你答案,你也不知道他为什么要这样做。

我很多代码思维和技巧,都是学习同事的代码,我看到他们的代码时,和无际项目特训营老铁看我们代码的感觉是一样的,先是一脸懵逼,有些工作后,接触项目多了,才领悟其中的精髓。

刚开始我也不能理解他们的代码,感觉写的很复杂,搞不懂明明可以写的很简单,为什么要绕一个弯。

不过我把他们的代码保存起来了。

后面跳槽又做了几年,有次,领导安排了一个复杂点的新项目,需要自己独立从头到尾去做。

很多功能没做过,不知道怎么下手,摸着石头过河,用最笨的办法,先把功能实现。

后面把代码组织在一起的时候,又发现整个逻辑异常混乱和冲突。

举个简单的例子,一个LED灯指示设备联网状态,未接连上时,每200ms闪一次,连接上wifi时,每400ms闪一次,连接上路由器时,每600ms闪一次,连接上服务器时,常亮。

固定的闪烁效果,简单,但要考虑到通用性和扩展性,就难很多了。

为什么我要专门给点灯,写一个程序架构?

是因为LED需求太多了,LED大多数产品都有,而且每个产品LED数量,需要的闪烁效果都不同,每次重复去写,费时费力。

所以我把LED闪烁,设计成独立的功能模块,并考虑到了扩展性和移植性。

需要修改LED数量,直接修改枚举量就好了,需要增加LED闪烁效果,直接添加一个波形数组就好了,后续算法会根据数组的值,自动输出相应的波形。

架构定好,下次类似产品功能的需求,我改一下,只需要几分钟。

所以,程序写的咋样,不是看代码写得多漂亮,或者用了什么高级语法,而是看是否精准解决需求。

除此以外,所有花里胡哨的技巧,都是脱裤子放屁。

代码稳定性,主要体现在一些复杂的项目上,一些简单的项目,没多少功能,硬调也能调出来。

所以,我觉得,想把代码写稳定,最主要的就是程序架构的设计。

如果架构设计不好,会导致代码难以维护、容易出错、功能扩展困难、稳定性差、调试困难、硬件兼容性差等问题。

好的程序架构,我觉得核心是要把控两点:

一、程序"地基"也就是整个项目,所有功能的"管理者"。比如RTOS,就是充当这样的角色。

很多复杂的单片机项目,都会上RTOS,就是保证地基是稳定,降低对工程师的技能要求。

写一个系统,和移植一个系统用,完全不是一个难度级别。

不过,我还是比较喜欢用"裸机"写程序,然后采用自己设计的轻量任务调度系统。

08e4ed92-907a-11ef-a511-92fbcf53809c.png

这是一个简单的轮询式任务调度系统,通过一个定时器中断来触发任务调度。相对RTOS来说,有以下优势:

①简单,资源占用少不需要复杂的任务管理数据结构和调度算法,因此占用的内存和CPU资源较少,特别适合资源受限的单片机,之前这个架构多次用于51单片机的项目。

②能完全掌控代码都是自己写的,相对移植RTOS来说,更能掌控,减少由于对系统不熟,给产品埋雷的风险。任务也是按顺序执行的,没有复杂的任务切换,调试时更容易跟踪和分析问题。 ③任务分离通过任务创建函数OS_CreatTask,将不同的功能分配给不同的任务。这种分离确保了每个任务只关注一件事情,提高了代码的可读性和可维护性。

④灵活性创建任务时,可以为每个任务分配不同执行频率,从而调整任务执行顺序,可以很灵活地控制任务执行,也非常适合周期性的任务。

⑤减少CPU占用,响应更快虽然在这个架构中没有明确的任务优先级,但可以通过调整任务的执行频率或顺序,来间接实现优先级控制。

传统while(1)死循环的用法,CPU一直在忙碌地执行某个代码块,而轮询式架构可以让CPU在没有任务执行时,处于空闲状态,一旦任务准备好执行,它可以立即开始运行,减少响应时间。 不过有一点,需要人为控制每个任务的代码效率,尽量不要有延时高的代码。 ⑤扩展性强虽然架构简单,但通过增加任务和调整调度逻辑,系统仍然可以扩展以支持更多的功能,比如增加现场切换功能和任务优先级管理,即是最精简的RTOS系统。 这种轮询式任务调度系统,虽然不支持真正的并发执行,但以更简单,高效的方式来管理多个任务,对于大多数的单片机项目来说,其实也够了。至少我还没碰到过,非要上RTOS才能完成的产品。

这个架构也有配套的开源视频,是我2018年录着玩的,不过代码已申请版权,非学员不能直接用于自己项目,可以学习这种编程思维,要的找我安排。

0908968e-907a-11ef-a511-92fbcf53809c.png

二、功能模块化如果是项目功能比较多,一定要采用模块化的方式,以便于后期的代码维护和移植。 拿我们无际特训营项目6的代码举例,创建了3个任务,分别管理硬件层、中间层、应用层的功能。

092258bc-907a-11ef-a511-92fbcf53809c.png

1.硬件层主要是单片机外设,以及一些外围芯片的驱动程序,比如定时器、LED、语音输出、按键、串口、ADC、EEPROM

0944ae76-907a-11ef-a511-92fbcf53809c.png

然后不同的硬件驱动程序也是相互独立的。

0967c7da-907a-11ef-a511-92fbcf53809c.png

2.中间层主要是一些协议的解析,比如mqtt、lora4G等,还有就是一些硬件层的应用程序,比如屏显示图案,电池电量检测逻辑,外电检测逻辑等。

097537c6-907a-11ef-a511-92fbcf53809c.png

不同的功能程序也是相互独立的。

0999d27a-907a-11ef-a511-92fbcf53809c.png

3.应用层就是具体的产品逻辑功能实现代码,比如菜单系统,防盗报警模式逻辑等等。

09a701f2-907a-11ef-a511-92fbcf53809c.png

我们在做功能的时候,也要有架构的思维,需要考虑到后续功能的扩展和移植。

比如我们做菜单的时候,会考虑到后期如果项目需要增加或删减界面,怎么设计比较方便灵活。

我们目前的做法是通过结构体数组来管理每个界面,然后通过双向链表让各界面建立联系。

09c88174-907a-11ef-a511-92fbcf53809c.png

类似的还有很多,比如说LED,按键这种,基本也是每个产品的刚需。

三、怎么去锻炼架构思维和能力?一般的工程师,会在工作了3,4年左右,才能意识到程序架构的必要性,也取决于你什么时候能有机会独立完成复杂的项目,这个时候你会发现,原来的知识体系不够用。

心态上不用太着急和焦虑,按照正确的方向努力,很快就能具备架构设计能力。

一般流程是这样的。1.先实现功能先不要考虑架构,先把功能实现出来,再从功能里面找规律。

比如一个按键检测代码,和10个按键,其实也就是加个for循环,代码就能复用。

比如LED灯的特效,其本质就是输出的高低电平波形持续的时间不一样,我们是否能用一个数组来存储波形数据,通过定时器配合小算法来输出波形呢? 这些代码,都是要一步步迭代的,可能修改10次,就比较完美了,不要要求一写就接近完美,容易自闭。 还有就是多接触优秀的工程师和项目,没条件的可以看看STM32固件库代码,看看蓝牙协议栈,看看RTOS,这些都是开源的产品级代码。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6078

    文章

    45589

    浏览量

    673906
  • 代码
    +关注

    关注

    30

    文章

    4977

    浏览量

    74407

原文标题:如何编写稳定的单片机代码?

文章出处:【微信号:nanshuqg,微信公众号:无际单片机编程】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    项目选型必看:单片机与PLC究竟该怎么选?

    单片机更便宜、更灵活,但在工业现场,PLC的可靠性、稳定性、易用性和高维护性是单片机难以替代的。 PLC = 单片机 + 工业电源 + IO隔离 + 工业外壳 + 实时操作系统 + 通
    的头像 发表于 03-27 15:47 252次阅读
    项目选型必看:<b class='flag-5'>单片机</b>与PLC究竟该怎么选?

    纽扣电池给单片机供电问题

    差异性,导致单片机的供电可能是3.1V,也可能是2.9V,这样的差异会影响到单片机的基准电压导致adc采样值不稳定。对于这种情况,我该如何处理,使得使用不同纽扣电池时,adc采样值尽可能稳定
    发表于 03-14 14:57

    单片机C语言的误区介绍

    经常见网友们说,代码不能写太多了包括注释,单片机的ROM只有几个K的空间,其实这是表面问题的误解。 1、注释是写不进去hex文件的,下载到芯片里的只有你的有效代码汇编以后生成的机器码,注释自动编译器
    发表于 12-22 12:45

    51单片机RS485编程实例资料

    详细介绍51单片机RS485通信接线和编程代码
    发表于 10-20 14:57 6次下载

    单片机原理及应用详解

    单片机(Microcontroller Unit, MCC)  是一种集成计算机核心功能(CPU、存储器、I/O接口等)的微型芯片,广泛应用于嵌入式系统中。以下是其原理及应用的详细介绍: 一、单片机
    的头像 发表于 08-11 13:57 2829次阅读

    单片机用什么封装

    单片机封装是将芯片内部电路与外部引脚连接并包裹保护的结构,不仅影响单片机的安装方式、适用场景,还与电路设计的紧凑性、散热性能密切相关。不同封装类型各有特点,适配从简单电路到复杂系统的多样化需求
    的头像 发表于 08-01 13:47 1620次阅读

    什么单片机比较耐用

            在工业控制、户外设备、医疗仪器等场景中,单片机的耐用性直接决定了设备的稳定运行与维护成本。耐用的单片机通常具备宽温工作范围、强抗干扰能力、稳定的电源适应性和长寿命的硬件
    的头像 发表于 07-31 13:48 921次阅读

    单片机的储存优点是什么

    场景。深圳市安凯星科技有限公司在单片机应用开发中,充分利用这些储存优点,为拓邦、朗科、安徽龙多等客户打造了高效稳定的解决方案。 1.集成度高,节省硬件空间 单片机将程序存储器(ROM)、数据存储器(RAM)与 CPU、I/O 接
    的头像 发表于 07-31 10:09 831次阅读

    单片机采用什么电流输出

    单片机的电流输出特性与其内部电路设计和应用场景密切相关,既包含自身工作时的微弱电流,也涉及通过外部电路扩展后的驱动电流。了解单片机的电流输出特点,是实现稳定控制外部设备的基础。 单片机
    的头像 发表于 07-30 11:13 1321次阅读

    怎么测单片机系统频率

    单片机系统频率是指单片机工作时的时钟频率,它直接影响单片机的运行速度和处理能力,准确测量系统频率对单片机应用开发、程序调试和性能优化具有重要意义。测量
    的头像 发表于 07-25 11:39 1095次阅读

    单片机怎么驱动电机?

    在各类自动化设备和智能装置中,电机是重要的执行部件,而单片机作为控制核心,需要通过特定的方式驱动电机运转。单片机驱动电机并非直接连接即可,而是要根据电机类型和功率,搭配合适的驱动电路,才能实现稳定
    的头像 发表于 07-25 09:31 1345次阅读

    单片机怎么烧程序

    单片机烧程序是将编写好的程序代码写入单片机内部存储单元,让单片机按照预设逻辑工作的过程,是单片机应用开发中不可或缺的环节。无论是简单的灯光控
    的头像 发表于 07-23 11:47 2052次阅读

    单片机直流电机调速原理

    在工业自动化、智能设备等领域,直流电机的调速控制至关重要,而单片机凭借其灵活的控制能力,成为实现直流电机精准调速的核心部件。单片机直流电机调速技术通过程序控制,能让电机在不同工况下保持稳定的转速
    的头像 发表于 07-17 13:42 925次阅读

    给予单片机的温度控制系统设计

    在工业生产、智能家居等领域,温度的稳定控制至关重要,基于单片机的温度控制系统凭借灵活、高效的特点被广泛应用,其设计原理与实现方式值得深入探讨。 基于单片机的温度控制系统主要由单片机、温
    的头像 发表于 07-16 10:57 839次阅读

    KF32A136系列单片机产品介绍

    F32A136 系列单片机是基于 KF32 内核架构开发的单片机
    的头像 发表于 06-27 11:42 2823次阅读
    KF32A136系列<b class='flag-5'>单片机</b>产品介绍