撸代码时,有哪些习惯一定要坚持?

我从2011年开始做单片机开发,一直保持以下撸代码的习惯。

1.做好代码版本管理

有些人,喜欢一个程序干到底,直到实现全部的产品功能,我以前做51单片机的项目就是这样。

如果功能比较多的产品,我不建议这样做,迟早有一天,有一个项目,会让你崩溃的,特别是还不具备模块化编程能力的时候

之前我就踩过几次这种坑,一个程序版本实现了很多个功能,后面新增功能的时候,突然发现了一个BUG,怎么都调不出来。

这时候,如果有上一个版本,可以用上一个版本的代码,一点点代码复制过去看看,到底是哪个代码造成的。

从那次以后,我就养成了做代码版本管理的习惯,比如V1.0,V1.1,V1.2.....

然后每个程序版本里面,我都会写一个文档,描述下历史版本实现的功能记录,以防后面忘了。

2.多学习优秀的代码和思维

刚工作那会,主要用STC的51单片机做项目,主要维护之前工程师遗留的代码,升级产品功能为主,基本是一堆屎山代码,实现功能就行了。

不会考虑怎么把代码写得更好,主要是自己当时也没那能力,项目又急,能改出来应付工作就不错了,有时项目急,我逻辑又理不清,甚至用了goto语句走了捷径,可能很多人都没见过。

工作了几年,一直是维持在这种水平,没有提升,因为接触不到更复杂的项目,接触不到好的编程思维和代码。

后面跳槽到一家公司,接收了一个网关项目,需要自己从0到1,完成整个项目的代码。

这个项目难度,已经超过了我的知识范围,主要有两个问题:

第一,很多功能没做过,不知道啥原理

第二,功能太多了,不知道怎么很好地把它们整合协调起来。

我是怎么解决这两个问题的呢?

第一个问题,最快的方式就是问同部门的研发同事。

不过不要指望别人会手把手教你,哪怕领导发话,别人也没这义务。

最关键的,不是指望让领导去给他下发命令,就能让他带你,而是看自己懂不懂得做人的。

举个例子:有些老铁来找我领单片机入门到高级的教程+工具包,我都是无套路直接发链接。

为什么要在我的朋友圈才发?

因为我是卖课佬,我觉得我们的项目课确实能帮到一些人,成就一些人,万一哪天你需要,我们又正好专业,各取所需共赢,我觉得没毛病。

但,我也深知,要让别人认可你,那就先贡献价值出来,所以我就不断输出自己经验和送粉丝教程+工具包了。

我感觉人和人之间,挺有意思,也差别挺大。

有些人很懂得感恩,还会给我发个小惊喜,收不收看我有没有给到他对应的价值了。

有些人,趾高气昂,理所当然,像我欠了他的一样。

我就想,怎么会有这种傻杯,然后拉黑了。

扯远了。

回到找同事帮忙的问题,也是同理,你得付出相应的价值,得请吃饭、得请喝奶茶、帮的忙多了得送礼....这不是潜规则,是对别人起码的尊重。

不能因为领导发话了,叫他去带你,你就能像个伸手党一样,一直索取他的价值,不信?你试试多问几个问题以后,看他鸟不鸟你。

第二个问题,功能太多了,不知道怎么很好地把它们整合协调起来。

这个其实最难,因为涉及到程序架构的问题,不是某个功能点,更多的是经验积累到一定程度后,再学习别人优秀的程序架构,突然开悟了。

我是参考别人工程师写的代码,一点点积累起来的,然后根据时间片轮询原理,设计了一个程序架构,我在2019年也录过这个程序架构的教程。

老规矩,有礼貌的粉丝,可以找我安排。

编程思维、高阶代码技巧、程序架构这些,如果能冲我们无际单片机项目特训营,系统把我们几个项目做完,那直接就是走捷径了,都是我们踩坑10年以上总结出来的精华。

3.重视模块化

我第一次重视程序模块化,项目代码量编译完大概70kb+。

什么是模块化?

举个例子,以下两段代码,分别是非模块化写法和模块化写法:

非模块化写法:

C
#include <reg51.h> // 假设是51单片机

void main() {
    //
硬件初始化
    P1 = 0xFF; // 设置P1口为输入
    IT0 = 1;    // 设置外部中断0为下降沿触发
    EX0 = 1;    // 使能外部中断0
    EA = 1;     // 开启全局中断

    // 主循环
    while(1) {
        //
功能实现
        if(P1_0 == 0) {
            P1 = ~P1; //
如果P1.0被按下,翻转P1口的状态
        }
    }
}

//
外部中断0服务程序
void exint0() interrupt 0 {
    //
中断处理
    P1 = P1 << 1; // 每次中断,将P1口的值左移一位
}

在这个例子中,硬件初始化、主循环和中断服务程序都混合在同一个.c文件中,阅读和维护起来会困难很多,特别是后期随着代码越来越多。

模块化写法:

C
// hardware.h
#ifndef HARDWARE_H
#define HARDWARE_H

void init_hardware();

#endif

// hardware.c
#include "hardware.h"

void init_hardware() {
    P1 = 0xFF; //
设置P1口为输入
    IT0 = 1;    // 设置外部中断0为下降沿触发
    EX0 = 1;    // 使能外部中断0
    EA = 1;     // 开启全局中断
}

// main.c
#include "hardware.h"
#include <reg51.h>

void main() {
    init_hardware(); // 初始化硬件

    while(1) {
        // 主循环功能实现
        if(P1_0 == 0) {
            P1 = ~P1; // 如果P1.0被按下,翻转P1口的状态
        }
    }
}

// exint0.c
#include <reg51.h>

// 外部中断0服务程序
void exint0() interrupt 0 {
    // 中断处理
    P1 = P1 << 1; // 每次中断,将P1口的值左移一位
}

在这个模块化的例子中,我们将硬件初始化放到了hardware.c和hardware.h中,主循环放在main.c中,而中断服务程序放在exint0.c中。这样,每个文件都有一个明确的作用,代码的结构更加清晰,也更好阅读和维护。

稍微复杂点的单片机项目,需要处理很多硬件接口和复杂的时序逻辑,还有各种产品业务逻辑组合,所以模块化尤其重要。

上面只是举了两个入门级模块化写法,高阶的模块化,远不止这些,首先是程序文件架构的模块化,分硬件层、中间层、应用层。

怎么实现多层之间依赖最少,这样后期万一需要更换单片机,只需要修改硬件层驱动代码就好了。

然后是里面每个功能模块化,怎么写方便后期增减功能。

这些其实都是系统的学问,所到之处全是细节,我们无际单片机特训营,都是通过这些思维和编程方式做的,特别是项目3和6。

提升这块的能力,主动学习意识和机遇都很重要,有些工程师做了4,5年,如果公司一直做简单的项目,那也是提升不了的,需要自己通过业余的时间,不断看别人代码摸索。

4.有条件,换个好点的椅子

撸代码的,长时间对电脑,经常一坐就是几个小时,好点的椅子能缓解颈椎、腰椎的疲劳。如果能换个立式办公桌就更好了。

5.不要做一个看完不点赞的冷漠青年

不知不觉,又写了两个多小时,原创不易,发财小手点起来...


最近很多粉丝问我单片机怎么学,我根据自己从业十年经验,累积耗时一个月,精心整理一份「单

片机最佳学习路径+单片机入门到高级教程+工具包」全部无偿分享给铁粉!!!

除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,让你迅速进阶成高手

教程资料包和详细的学习路径可以看我下面这篇文章的开头

《单片机入门到高级开挂学习路径(附教程+工具)》

《单片机入门到高级开挂学习路径(附教程+工具)》

《单片机入门到高级开挂学习路径(附教程+工具)》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/797535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何搭建APP分发平台分发平台搭建教程

搭建一个APP分发平台可以帮助开发者更好地分发和管理他们的应用程序。下面是一个简要的教程&#xff0c;介绍如何搭建一个APP分发平台。 1.确定需求和功能&#xff1a;首先&#xff0c;确定你的APP分发平台的需求和功能。考虑以下几个方面&#xff1a; 用户注册和登录&#xff…

Anritsu MS9740B与MS9740A 光谱分析仪 的区别?

MS9740B与MS9740A的主要区别在于测量处理时间的缩短和对高速信号处理技术的应用。MS9740B在保持原有功能和性能的同时&#xff0c;将测量处理时间缩短了一半。这一点通过提高生产效率和减少测量及检查时间来实现&#xff0c;从而提高了光有源设备制造商的生产力。此外&#xff…

mid转MP3怎么转?一分钟搞定~

MIDI&#xff08;Musical Instrument Digital Interface&#xff09;文件格式的诞生可以追溯到上世纪80年代&#xff0c;音频技术迅速崛起。为了让不同音乐设备之间能够互相通信&#xff0c;MIDI格式成为了音乐的标准。它不同于常见的音频文件格式&#xff0c;不包含实际的声音…

浮点数在内存中的存储【详解】

浮点数在内存中的存储 浮点数存储规则小数点后数值的二进制转换float和double存储图示优化存储方案E不全为0或不全为1E全为0E全为1 浮点数存储规则 大家都知道整型数据是以补码的方式存放在内存中。以下几个概念是需要知道的&#xff1a; 原码&#xff0c;补码&#xff0c;反…

汇编语言:寻址方式在结构化数据访问中的应用——计算人均收入

有一年多没有在CSDN上发博文了。人的工作重心总是有转移的&#xff0c;庆幸一直在做着有意义的事。   今天的内容&#xff0c;是为汇编语言课程更新一个实验项目。      本方案修改自王爽编《汇编语言》第&#xff14;版P172“实验7寻址方式在结构化数据访问中的应用” …

探索未来游戏:生成式人工智能AI如何重塑你的游戏世界?

生成式人工智能&#xff08;Generative AI&#xff09;正以前所未有的速度改变着各行各业的运作模式。其中&#xff0c;游戏产业作为科技应用的前沿阵地&#xff0c;正经历着前所未有的变革。本文将探讨生成式人工智能如何重塑游戏产业&#xff0c;以及这一变革背后的深远影响。…

一、Docker部署GitLab(详细步骤)

Docker部署GitLab&#xff08;详细步骤&#xff09; 一、拉取镜像二、启动容器三、修改配置四、修改密码五、浏览器访问 一、拉取镜像 docker安装教程&#xff1a;https://qingsi.blog.csdn.net/article/details/131270071 docker pull gitlab/gitlab-ce:latest二、启动容器 …

邮件服务器:Postfix

文章目录 邮件服务器的功能与工作原理电子邮件的问题Mail server与DNS 之间的关系邮件传输所需要的组件(MTA、MUA、MDA)以及相关协议用户收信时服务器端所提供的相关协议&#xff1a;MRA电子邮件的数据内容 使用Postfix与Dovecot部署邮件系统部署基础的电子邮件系统配置Postfix…

政校企三方牵手打造新质生产力,共建城市供应链安全检测中心

​4月3日 十堰市经开区政府 x 开源网安 战略合作签约仪式 圆满完成 4月3日&#xff0c;开源网安与十堰市经济技术开发区政府、湖北工业职业技术学院、十堰市经开建投签约仪式在十堰国际会展中心圆满完成。本次签约后&#xff0c;签约方将共建十堰市智能网联汽车网络安全测试…

什么是数据治理?你都了解吗?

在当今数字化时代&#xff0c;数据已成为企业重要的战略资产。有效管理数据对于企业提高运营效率、降低成本、做出更好的决策至关重要。数据治理作为一种重要的管理方法&#xff0c;可以帮助企业确保数据的质量、安全、合规性和有效利用。 一、数据治理的定义与重要性 近日&a…

(南京观海微电子)——TFT驱动原理

TFT液晶显示器件是指在液晶显示器件的每个像素上都连接一个薄膜场效应晶体管。这个场效应管制作在液晶显示器件的玻璃上。每个场效应管独立驱动一个像素&#xff0c;从而可以实现高速度、高亮度、高对比度的显示效果。 TFT液晶显示器件的驱动特性取决于场效应管的工作特性。场效…

SpringBoot实现邮箱验证

目录 1、开启邮箱IMAP/SMTP服务&#xff0c;获取授权码 2、相关代码 1、使用配置Redis&#xff08;用于存储验证码&#xff0c;具有时效性&#xff09; 2、邮箱依赖和hutool&#xff08;用于随机生成验证码&#xff09; 3、配置Redis和邮箱信息 4、开启Redis服务 5、编写发送…

海外代理IP购买指南:住宅IP代理VS.数据中心代理IP

在选择海外IP代理服务时&#xff0c;您将面临一个关键的问题&#xff1a;是选择住宅代理IP还是数据中心代理IP&#xff1f;这两者之间存在着根本性的不同&#xff0c;涉及到性能、隐私和成本等方面的考虑。住宅代理IP通常来自真实的住宅网络连接&#xff0c;更难被检测到。数据…

Winforms中的ArgumentOutOfRangeException异常

// 定时器事件 只处理计时逻辑 每隔1000毫秒会被调用。 private void timer1_Tick(object sender, EventArgs e) {count; //记录当前秒label3.Text (time - count).ToString() " 秒"; progressBar1.Value count;if(count time){timer1.Stop(); //关闭计时Sys…

MotionBuilder 脚本执行

目录 MediaPipe_Pose_in_MotionBuilder 你可以用以下几种方式执行你的脚本&#xff1a; MediaPipe_Pose_in_MotionBuilder https://github.com/Ndgt/MediaPipe_Pose_in_MotionBuilder/blob/main/PoseLandmark.py tcp通信 https://github.com/nils-soderman/motionbuilder-s…

解决Android Studio Loading Devices问题

目录 一、解决办法&#xff08;普通&#xff09;&#xff1a; 二、解决办法的优化 三、解决办法的进一步优化 问题&#xff1a;windows 11 电脑&#xff0c;每次开机&#xff0c;打开Android Studio,都会显示Loading Devices&#xff0c;连接不上设备。 原因&#xff1a;adb…

css实现更改checkbox的样式;更改checkbox选中后的背景色;更改checkbox选中后的icon

<input class"check-input" type"checkbox"> .check-input {width: 16px;height: 16px;} /* 设置默认的checkbox样式 */input.check-input[type"checkbox"] {-webkit-appearance: none; /* 移除默认样式 */border: 1px solid #999;outl…

鹏哥C语言复习——结构体

目录 结构体声明&#xff1a; 结构体内存存储相关介绍&#xff1a; 结构体的初始化与使用&#xff1a; 结构体的初始化&#xff1a; 结构体的使用&#xff1a; 结构体对齐&#xff1a; 结构体对齐原则解释&#xff1a; 结构体对齐存在的原因&#xff1a; #pragma pack…

人工智能研究生前置知识—Anaconda与python工作环境

人工智能研究生前置知识—Anaconda与python工作环境 python环境管理 python工作环境的管理是需要满足的基本条件&#xff0c;指的是不同的python版本之间的切换。或者说是允许安装不同版本的python 解决&#xff1a;conda是一个跨平台的包管理工具&#xff0c;其环境管理功能允…

Docker容器与虚拟化技术:OpenEuler 部署 ES 与 Kibana

目录 一、实验 1.环境 2.OpenEuler 部署 ES (EalasticSearch) 3.OpenEuler 部署 Kibana 4.部署 Elasticvue插件 5.使用cpolar内网穿透 6.使用Elasticvue 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统架构版本IP备注LinuxopenEuler22.03 LTS SP2 1…