软件设计——随手笔记

  • 头文件包含其它头文件尽量少
  • include头文件会导致文件体积增大吗?不会。最后生成的可执行文件.hex里面只有函数定义、全局变量、以及一些字符串常量等。这些才会占据.hex文件的空间。c文件里定义变量和函数,h文件里声明变量(有的用extern声明对应c文件的变量成外部变量)和函数
  • 软件中标志位变量,计数变量什么时候复位非常重要,要么是置位后马上复位,要么在其它地方复位,计数变量一般是计满值触发执行后马上复位
  • 全局变量的共用时间点非常关键,不要这边在改变,那边却要使用改变前的值,这样程序就会出现奇怪值
  • 软件中同样需要设置测试点
  • 软件看门狗必须加上
  • 端口的输入输出模式很重要,模式不对,就达不到效果,比如逻辑电平输出就不能设置推挽输出,而是准双向
  • 用串口调试助手时,把杀毒软件退出,否则影响串口稳定
  • 主函数中必须有while(1)循环,否则程序会不断复位
  • 程序的头文件必须对应所用的芯片型号,否则会出现奇怪的问题
  • 软件设置中内存模式DATA和XDATA是有差别的
  • 看门狗喂狗是在主循环里喂,不要在中断里或多处喂狗
  • 函数应该是一个入口,一个出口
  • 一个系统程序执行逻辑时,某一个设置应该是在某一种运行模式的条件下生效的,所以系统需要分割成不同运行模式
  • 程序里多写一些测试打印函数,把想知道的作为打印的数据,单片机寄存器的值可以作为判断条件进行打印,把看不到的值显示出来,比如串口不响应,可以把串口接收的原始数据打印出来,把寄存器的值打印出来,看有没有丢包或错位,串口数据帧接收一定要先判断帧头正确了再继续计数接收,不能来数据就计数接收,容易出现错位问题当软件无法找到奇怪问题的原因时,转去检查电信号是否正常
  • 用条件编译来打开或关闭log打印的语句,也可以关闭或打开某个功能模块
  • 当启用新的功能模块时,进入低功耗模式前记得关闭对应的模块,避免出现莫名其妙静态电流就变大了
  • 串口助手选的是无校验,程序里把发送的字节数据赋给ACC,再把ACC赋给SBUF,结果串口收到的数据没错,发出来的一直不对,原来ACC寄存器是用于校验的,如果无校验,就直接把数据给SBUF就行
  • 芯片的寄存器总数取决于存放寄存器地址的位宽度(地址线条数),比如位宽度是4,那么就有16个寄存器地址,地址是该寄存器在内存中唯一位置标识,地址好比房间号,寄存器好比房间,寄存器的值就是房间里的物品,寄存器类型又分多种,各有用途
  • 芯片数据手册中参数的典型值表示默认值,也是寄存器的默认值
  • 各种变量初始化:整型和浮点型初始化为0,字符初始化为’\0’,字符串初始化为" ",可以使用memset函数(按照字节进行填充),指针初始化为NULL,但如果没有重新给指针分配内存,就会出现难以预料的错误,所以可以用malloc等函数给指针分配内存,用完指针后释放它,并将指针置为NULL,否则为编程野指针,结构体初始化可以用memset
  • 真正的模块化,并不是文本意义上的,而是逻辑意义上的。一个模块应该像一个电路芯片,它有定义良好的输入和输出。它的名字叫做“函数”。每一个函数都有明确的输入(参数)和输出(返回值),同一个文件里可以包含多个函数,所以你其实根本不需要把代码分开在多个文件或者目录里面,同样可以完成代码的模块化。
  • 避免写太长的函数。如果发现函数太大了,就应该把它拆分成几个更小的。通常我写的函数长度都不超过40行。
  • 制造小的工具函数。每个函数只做一件简单的事情。函数既共享一些代码,又是独立函数。
  • 避免使用全局变量和类成员来传递信息,尽量使用局部变量和参数。
  • 帮助大大减少写代码注释的方法:
    使用有意义的函数和变量名字。
    局部变量应该尽量接近使用它的地方。
    局部变量名字应该简短。
    不要重用局部变量。
    把复杂的逻辑提取出去,做成“帮助函数”。
    把复杂的表达式提取出去,做成中间变量。
    在合理的地方换行。
  • 避免使用自增减表达式(i++,++i,i–,–i)。
  • 永远不要省略花括号。合理使用括号,不要盲目依赖操作符优先级。
  • 避免使用continue和break。循环语句(for,while)里面出现return是没问题的
  • 写代码有一条重要的原则:如果有更加直接,更加清晰的写法,就选择它,即使它看起来更长,更笨,也一样选择它。
  • 代码里面很少出现只有一个分支的if语句。我写出的if语句,大部分都有两个分支,每个if语句都有两个分支的理由是:如果if的条件成立,你做某件事情;但是如果if的条件不成立,你应该知道要做什么另外的事情。不管你的if有没有else,你终究是逃不掉,必须得思考这个问题的。
  • 代码可靠的一种通用思想:穷举所有的情况,不漏掉任何一个。尽量不要产生null指针。尽量不要用null来初始化变量,函数尽量不要返回null。
  • 防止过度工程的原则如下:
    先把眼前的问题解决掉,解决好,再考虑将来的扩展问题。先写出可用的代码,反复推敲,再考虑是否需要重用的问题。先写出可用,简单,明显没有bug的代码,再考虑测试的问题
  • Dev C++开发软件可以运行C语言基础编程,查看内存情况
  • 对于软件功能模块化设计,可以使用条件编译对代码块进行选择性编译,比如
    #define configUSE_COMM 1
    #if (configUSE_COMM == 1)
    代码块1
    #else
    代码块2
    #endif
    当这个宏定义为0时,就不执行代码块1了,很方便
  • 开发环境只是一种工具,做同一件事可以用多种不同的工具来完成它,就看这工具能不能做到而已
  • 赋值时一定确保左右两边的数据类型一致,否则会出错或运行奇怪
  • 不同的编译器理解为对编码翻译结果(机器码)不同,比如同一个代码文件,编译器A可以正确翻译,编译器B却无法翻译一些代码,编译器可以比喻成不同国家的人,对同一段文章的不同理解。不同编译器要求编码的语法是有所差异的,所以更换编译器后,编码格式或语法就要做相应的修改
  • 用gpio模拟串口收发通讯:串口协议中高电平表示空闲,拉低后表示通信开始。波特率9600,是1s内传送9600个bit,一个bit所需要的时间为 1000000us / 9600 = 104.166 us,也就是104us。发送数据采用while结合delay的阻塞式,比较占用cpu,不能做其他任务,采用定时器定时104us发送更高效,接收数据必须采用定时器中断,中断时间为52us,在接收到下降沿中断来临的时候,开启定时器中断
  • 结构体中的冒号表示位域,就是把一个字节的八个位分成不同区域,存储不需占用一个字节的信息,冒号右边是区域的位数,位域跟结构体成员使用方法一样
  • 单片机定时器定时计算方法:
    对12MHz晶振 1个机器周期 1us 12/fosc = 1us
    方式1 16位定时器最大时间间隔 = 2^16 = 65.536ms
    方式2 8位定时器最大时间间隔 = 2^8 = 0.256ms =256 us
    定时5ms,计算计时器初值 M = 2^K-XFosc/12 12MHz
    方式0: K=13,X=5ms,Fosc=12MHz 则 M = 2^13 - 5
    10(-3)*12*106/12= 3192 = 0x0C78
    THx = 0CH,TLx = 78H
  • 单片机C语言unsigned char code table[],
    code的作用是告诉单片机,我定义的数据要放在ROM(程序存储区)里面,写入后就不能再更改

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款旅游类智能体的开发,来体验一下我的智能体『​​​​​​​厦门CityWalk』

目录 1.1、智能体运行效果 1.2、创作灵感来源 1.3、如何制作智能体 1.4、可能会遇到的几个问题 1.5、快速调优指南 『厦门CityWalk🚀』我的优质智能体:https://0nxj3k.smartapps.baidu.com/?_swebfr1&_swebScene3621000000000000 在当今这个全…

Bytebase 2.22.3 - 一键回滚 PostgreSQL DML 变更

🚀 新功能 支持一键回滚 PostgreSQL DML 变更。 🎄 改进 优化 DML 事前备份和回滚体验: 引导用户创建 bbdataarchive 数据库。如果没有 bbdataarchive 数据库,无法开启备份功。用户现在可以在创建工单之后开启或关闭备份功能&a…

Python | Leetcode Python题解之第437题路径总和III

题目: 题解: class Solution:def pathSum(self, root: TreeNode, targetSum: int) -> int:prefix collections.defaultdict(int)prefix[0] 1def dfs(root, curr):if not root:return 0ret 0curr root.valret prefix[curr - targetSum]prefix[cu…

ROS学习笔记(四):使用 `ros2 run usb_cam usb_cam_node_exe` 启动 USB 摄像头

文章目录 前言1 安装 usb_cam 包2 启动 USB 摄像头3 订阅相机发布的节点信息并进行可视化3.1 使用 rqt_image_view3.2 使用 image_view3.3 使用 rviz 4 常见问题与解决方案4.1 摄像头未被识别4.2 相机显示异常4.3 如何指定不同的相机4.4 摄像头参数调整 5. 调试信息 5. 结论 前…

9.5K Star,开源在线网盘

Hi,骚年,我是大 G,公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注。 随着云存储的广泛应用,越来越多的人和企业需要一个简单、…

用Promise实现前端并发请求

/** * 构造假请求 */ async function request(url) {return new Promise((resolve) > {setTimeout(() > {resolve(url);},// Math.random() * 500 800,1000,);}); }请求一次,查看耗时,预计应该是1s: async function requestOnce() {c…

docker安装Portainer CE

docker安装Portainer CE 教程 1、简介 Portainer 是一款开源的容器管理工具,旨在帮助用户更轻松地管理 Docker 环境。无论您是 Docker 新手还是经验丰富的开发人员,Portainer 都提供了直观的用户界面,使您能够方便地创建、部署和监控容器。…

黑马头条day5- 延迟任务精准发布文章

这个过程主要是流程负责 但是我没有仔细的过所有的流程 需要多刷几遍 今天只是照着md文档执行了一下 运行起来没差错 主要实现文章定时发布 通过schedule模块作为延迟队列的任务 通过redis实现的延迟任务 具体 实现还要在多走几遍流程 逻辑一点不清楚 没看网课 这节要多看几遍…

Redis 篇-深入了解 Redis 中的 RESP 通信协议与内存回收(过期 key 处理、内存淘汰策略)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 Redis 通信协议 - RESP 协议 2.0 Redis 内存回收 2.1 Redis 内存回收 - 过期 key 处理 2.1.1 Redis 是如何知道一个 Key 是否过期呢? 2.1.2 是不是 TT…

GESP等级考试C++二级-数学函数

C的cmath库中有丰富的数学函数,通过这些函数可以进行相应的数学计算。 1 cmath库的导入 通过import指令导入cmath库,代码如图1所示。 图1 导入cmath库的代码 2 abs()函数 abs()函数用来获取指定数的绝对值,代码如图2所示。 图2 abs()函数…

X86下一文带你构建Apollo9.0运行环境(基于Ubuntu20.04避坑版)

X86下一文带你构建Apollo9.0运行环境基于Ubuntu20.04避坑版 前言准备安装基础软件1.安装Docker19.03安装Nvidia驱动安装配置Nvidia container toolkit 下载Apollo源码(笔者下载的是releases下9.0.0版本,大家可以参考)编译Apollo9.0下载资源包…

vue-cli,element-plus,axios,proxy

一、vue-cli vue-cli俗称vue脚手架,是vue官方提供的快速生成vue 工程化项目的工具。 1.官网:https://cn.vuejs.org/ 中文官网: https://cli.vuejs.org/zh/ 特点:基于webpack,功能丰富且易于扩展,支持创建vue2和vu…

对话总结:Scale AI的创始人兼CEO Alex Wang

AI的三大支柱 计算:主要由大公司如NVIDIA推动。算法:顶尖实验室如OpenAI主导。数据:Scale致力于推动数据进展。前沿数据的重要性 与人类智能相比较,前沿数据是AI发展的关键。互联网数据是机器与人类合作的结果。语言模型的发展 第一阶段:原始的Transformer论文和GPT的小规…

一书直接讲透自然语言处理《Getting Started with Google BERT_ Build and train》

《Getting Started with Google BERT: Build and Train》是一本面向初学者和中级读者的指南,旨在帮助他们理解和使用Google的BERT(Bidirectional Encoder Representations from Transformers)模型。BERT是近年来自然语言处理(NLP&…

Linux下的git开篇第一文:git的意义

目录 1.git版本控制器 2.git gitee&&github 3.Linux中gitee的使用 ( 三板斧 git add git commit -m " " git push ) 4.git log 查看之前的修改信息 (所有提交日志) 5.git status 查看工作目录与本地…

透传 vs 非透传|数据传输效率与安全性的权衡及应用指南

官方原文:一分钟搞懂透传和非透传的区别-成都纵横指控 在当今数字化时代,数据传输已经成为各行各业的关键环节。在数据通信和物联网应用中,"透传"和"非透传"是两个常见且重要的概念。了解它们的区别,对于选择合适的通信方式至关重要。 什么是…

【java】前端RSA加密后端解密

目录 1. 说明2. 前端示例3. 后端示例3.1 pom依赖3.2 后端结构图3.3 DecryptHttpInputMessage3.4 ApiCryptoProperties3.5 TestController3.6 ApiCryptoUtil3.7 ApiDecryptParamResolver3.8 ApiDecryptRequestBodyAdvice3.9 ApiDecryptRsa3.10 ApiCryptoProperties3.11 KeyPair3…

C++(Qt)软件调试---内存调试器Dr.Memory(21)

C(Qt)软件调试—内存调试器Dr. Memory(21) 文章目录 C(Qt)软件调试---内存调试器Dr. Memory(21)[toc]1、概述🐜2、安装Dr.Memory🪲3、命令行使用Dr.Memory🦗4、Qt Creator集成使用Dr.Memory&…

excel快速入门(二)

Excel的概念说明 文章目录 Excel的概念说明常见术语说明单元格/单元格区域活动单元格/单元格区域行或列单元格引用相对引用绝对引用混合引用 Excel的常见格式说明单元格格式数字格式 Excel 工作表编辑鼠标指针介绍1.白色十字状2.单向黑色箭头状3.双向单竖线箭头状4.双向双竖线箭…

AI新掌舵:智享AI直播系统:直播界的新浪潮还是真人主播的终结者?

AI新掌舵:智享AI直播系统:直播界的新浪潮还是真人主播的终结者? 在数字化浪潮的汹涌澎湃中,人工智能(AI)以其前所未有的速度渗透至各行各业,其中,直播领域正经历着一场前所未有的变革…