STM32程序设计规范浅析

news2025/1/17 2:58:44

        这篇博客写到“STM32基础知识篇”里,一方面是一个很好地对过往工作的总结,另一方面也是整个专栏撰写计划的开端,古人云:良好的开端是成功的一半,在文章的最后详细地规划了整个专栏后期的更新计划。

       笔者前段时间休息的时候,把市面上很多开发板的教程也大致都看了一遍,也给自己一些创造思路或者写作方向吧,想要写好博客,就需要多阅读多思考并且不断地总结归纳,写作前多问自己几个为什么、相同问题多看不同教程的说法、相似技术多听不同人的说法,只有在写作前思路清晰,才可能在博客里把很多看似复杂的事说明白,尤其对于“STM32基础知识篇”这个专栏,目的就是夯实基础,提高进阶,那么怎样才算打好基础呢?

       如同那句名言:一百个读者就有一百个哈姆雷特!没有一个绝对性的答案,有人会说要学好C语言和数据结构;有人说要学好寄存器配置和多看数据手册;也有人说多实践动手才可能学好等还有很多种观点,当然上面这些观点都没有问题,但似乎又有什么都说了,但什么都没说的感觉,笔者个人的看法,学习任何一门技术都是先模仿再创造的过程,不断健全自己的知识体系,多动手多思考多总结,扩展知识面也逐步形成自己的知识网络去解决问题,因为研发总是一个不断遇到问题和不断解决问题的过程。

       在这篇博客围绕两个问题其一、STM32程序怎么编写才显得规范整齐,方便后期维护也提高程序的健壮性和稳定性;其二、“STM32基础知识篇”后续写些什么才能夯基固本,正真地从STM32入门学习到走在提高的路上,实际上这两个问题有着紧密的联系。

        关注过一些微信公众号,里面曾经看到过几篇讲STM32软件架构的文章,逼格很高写得很有文采,平心而论很难写到那样的高度, 但笔者结合近5年的产品研发经验和大家探讨STM32程序上的规范。

        首先需要把需求整明白这点非常重要,切勿啥也不想直接硬上写代码,那你写出的代码一定后期改动很大,举个例子,做过一个项目STM32外挂了adc和dac,以及需要根据adc的回读值给出不同占空比的pwm波给风扇调速,adc输入的是一个正弦波,即对一个正弦波进行adc采样,需要对一个外接IO进行上下边缘判断从而标记整个正弦波的开端,dac需要给定特殊的波形值,单片机内部需要存储校准系数,用来校准adc和dac的采样和输出值,需要两个串口和上游下游STM32通信,这时候就需要理清楚整体思路,把需求归纳好再动手。

       其次在动手编码的时候,很多初学以及工作过几年的人,都喜欢跑裸机先拿if else把逻辑堆起来,看起来功能好像实现了但没有考虑到整体架构等,会发现后续很难添加新功能,而且由于缺少分层的思想,整个程序会很凌乱可靠性稳定性差。这里我们是在做嵌入式MCU开发,不同于做PC端的WEB开发,需要更多地站在MCU角度思考整个程序的健壮性,这里有几点经验性的建议吧。 

     1. 尽量少开中断,有同学会在说整个需求里有多个串口,有多个需要定时计算的地方等,需要加几个定时器和串口中断才能满足需求,然后就真的开了很多中断,加上程序设计上没有分层,逻辑层和驱动层混乱,导致程序各种bug,这里大家需要学会用嘀嗒定时器、dma搬运等多种方法来合理减缓MCU的频繁进出中断的压力;

      2. 中断不做等待,有很多人喜欢在中断做一些复杂运算甚至等待delay操作,这些都是非常不好的习惯,导致MCU被一个中断事件持续打断,无法及时响应外部其他中断,正确的做法是在中断里只做赋值和置位操作,如果是裸机在while(1)循环的flag里去做后续操作,如果是系统freertos在任务集里做相应操作;

      3. 逻辑驱动分层,这是MCU编程的一个重要思想,同时关系到整个程序架构的稳定性和健壮性,在拿到一个需求后,大家需要想清楚哪些事情需要逻辑层处理,哪些事情驱动层就可以搞定,这样做下来,你会发现以后需求不管怎么变化,只是逻辑层随着变化,不伤筋不动骨,也不易出错;

       4. 通信握手等待,这点在MCU和MCU串口通信之间非常常见,比如外界干扰或者程序逻辑问题,导致报文收发不一致,做好报文握手和校验,以及超市等等,异常处理等后续逻辑也关乎整个产品的稳定性和可靠性;

       5. 合理存储数据,有很多项目需求有着掉电存储的需要,常见的有外挂eeprom和外挂flash,但这里大家也需要合理利用好MCU内部的flash空间,一方面可以进行IAP升级,一方面可以存储一些其他项目需求的数据等。

       聊完了一些STM32程序设计上的一些常见规范问题,再来思考“STM32基础知识篇”后续写些什么对于夯基固本更有意义,笔者也看了很多市面免费和付费的教程和网课,开卷有益,去粗取精,笔者这里会带着大家从零学习STM32这款经典的芯片(当然每个人的精力和能力有限,因此想着想搞完一个专栏再写另一个专栏,摊子不易铺得太大,现在正潜心想把“FPGA 20个例程”专栏收尾,再推出“FPGA 高速接口”专栏),具体内容大致如下(未完待遇):

1. STM32时钟配置运行机制;

2. STM32 GPIO类型和对应用途;

3. STM32定时器:RTC,看门狗,普通定时器,嘀嗒定时器的异同;

4. STM32 串口普通中断和空闲中断的对比;

5. STM32中dma的应用举例;

6. STM32内部模数转换adc的应用;

7. STM32内部数模转换dac的应用;

8. STM32 IO模拟IIC通信eeprom;

9. STM32 SPI读写外挂flash;

10. STM32的EXTI外部中断类型举例说明

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

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

相关文章

无人机遥感图像拼接与处理操作技术

【内容简述】: 无人机遥感图像采集流程: 无人机遥感监测介绍 无人机航线规划设计 无人机飞行软件操作 无人机航拍一般过程 无人机遥感图像拼接软件操作: Photoscan软件介绍 软件基本操作与实践 遥感图像拼接的一般流程 遥感图像分组拼接与点…

【centos】安装nvida CUDA平台附带安装cudnn库

目录1.安装 CUDAToolKit2.安装cudnn库1.安装 CUDAToolKit 使用 lspci | grep -i nvidia列出所有支持的GPU 安装内核开发依赖包: yum install kernel-devel查看内核版本号,用来看与开发包版本号是否一致: uname -r查看nvida显卡驱动&#…

设计模式之迭代器模式

Iterator design pattern 迭代器模式的概念、迭代器模式的结构、迭代器模式的优缺点、迭代器模式的使用场景、迭代器模式的实现示例、迭代器模式的源码分析 1、迭代器模式的概念 迭代器模式,即提供一种方法来顺序访问聚合对象内的元素,而不暴露聚合对象…

LeetCode HOT 100 —— 448. 找到所有数组中消失的数字

题目 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。 思路 原地哈希(简单模拟): 核心思路: 因为…

Python 和 PyQt5 实现打地鼠小游戏

Python 和 PyQt5 实现打地鼠小游戏 实现效果: 视频效果: https://live.csdn.net/v/264602https://live.csdn.net/v/264602 代码: import random import sysfrom PyQt5.QtCore import QBasicTimer, Qt, QTimer from PyQt5.QtGui import QCo…

CSS3【基础选择器、字体样式、文本样式、行高样式】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录基础选择器1. 标签选择器2. 类选择器3. id选择器字体和文本样式1.字体样式1.1 字体大小1.2 字体粗细1.3 字体样式(是否倾斜)1.4 常见字体系列…

JAVA中实现多线程-单例双重锁(DCL(Double Check Lock)双重锁检查)

一 .多线程 继承 Thread 类实现 Runnable 接口实现 Callable 接口线程池 重写run方法,创建对象,调用start()方法启动线程 1,新生状态 – 用new关键字建立一个线程后,该线程对象就处于新生状态。 – 处于新生状态的线程有自己的…

Netty前置知识

传统IO 这里以文件输入输出流:FileInputStream 、 FileOutputStream 来进行解释。由继承关系得知,这两个输入和输出类继承自 InputStream 和 OutputStream 这两个基础的输入、输出的抽象类,这时我们可以看到当我们需要读写文件的时候&#x…

leetcode--搜索

搜索1.深度优先搜索(DFS)(1)岛屿的最大面积(695)(2)省份数量(3)太平洋大西洋水流问题(417)2.回溯法(1)全排列(46)(2)组合(77)(3)单词搜…

C++ allocator设计内存管理器

文章目录allocator内存管理器基本属性类的设计关键功能的实现完整的内存管理器内存管理器的测试:设计自定义的String类。前情回顾: allocator内存管理类 allocator内存管理器 某些类需要在运行时分配可变大小的内存空间,一般来说我们使用容器…

从零搭建完整python自动化测试框架(UI自动化和接口自动化)

从零搭建完整python自动化测试框架(UI自动化和接口自动化) 文章目录 总体框架 PO模式、DDT数据驱动、关键字驱动 框架技术选择 框架运行结果 各用例对应的定义方式(PO/DDT) 测试执行结果 从零开始搭建项目 一、开发环境搭…

泪目,终于有P8大佬把困扰我多年的《计算机网络原理》全部讲明白了

前言 为什么网络协议这么重要呢?集群规模一大,我们首先想到的就是网络互通的问题;应用吞吐量压不上去,我们首先想到的也是网络互通的问题。所以,要成为技术牛人,搞定大系统,一定要过网络这一关&…

Mac怎么清理缓存?这两种方法都非常好用哦

与电脑系统或应用程序非常相似,您的Mac也有自己的系统缓存,它可以在后台临时存储数据,以加快软件安装速度并减少互联网数据使用量(通过Apple)。与电脑系统或应用程序类似,缓存数据可能会开始堆积——占用存…

unordered系列关联式容器以及哈希表原理实现

Ⅰ. unordered 系列关联式容器 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 log2nlog_2 nlog2​n,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的…

Android Studio Profiler 检查内存

Android Studio Profiler 检查内存简单介绍 如何使用? 第一步:点击Profiler按钮 第二步:选择 第三步:选择Capture heap dump 并点击Record 解释相关按钮的功能 垃圾桶按钮:用于强制执行垃圾回收事件的按钮&#xff…

LinkedList(JDK1.8)源码+底层数据结构分析

文章目录前言一、双向链表1.1 双向链表示意图1.2 LinkedList 属性1.3 Node 节点对象二、双向链表的操作2.1 添加元素-add2.2 删除元素-remove2.3 修改元素-set2.4 查询元素-get前言 双向链表是一种数据结构,由若干个节点构成,其中每个节点均由三部分构成…

疯狂游戏笔试题-2022秋招

编程题 1.假设数组第一个元素是k, 如果k在数组内, 则k*21 和 k*31也在数组内. 在已知k的情况下, 需算出另一个数是否也在数组内? 例子: 输入1,2 输出False 输入1,4 输出True 解题思路:暴力(doge),实在想不到其它好方法,有…

生成模型详解

一、生成模型的定义 给定的训练集X{x1,x2,...,xn}X \{x^1,x^2,...,x^n\}X{x1,x2,...,xn}隐变量zzz满足p(z)N(0,I)p(z) \mathcal{N} (0,I)p(z)N(0,I)定义一个条件分布pθ(x∣z)p_{\theta}(x|z)pθ​(x∣z),θ\thetaθ可以理解为生成模型的参数训练好模型后&#xff…

java高校宿舍费缴纳报修管理系统ssm1561

系统选用B/S模式,应用jsp技术, MySQL为后台数据库。系统主要包括个人中心、学生管理、宿管管理、宿舍信息管理、宿舍预订管理,在线报修管理、费用缴纳管理、投诉建议管理、论坛交流、系统管理等功能模块。 本系统采用从上往下的步骤开发&…

爬虫学习-数据解析三种方式:正则、bs4、xpath,以及一些实例操作

若出现乱码page_text page_text.encode(iso-8859-1).decode(gbk)或者查看源码head里面的说明,设置成相同的即可 数据解析原理概述 解析的局部的文本内容都会在标签之间或者标签对应的属性中进行储存数据解析就是 1、进行指定标签的定位2、标签或者标签对应的属性中…