STM32物联网实战开发(1)——全新的程序框架

news2024/11/28 20:41:33

        现在STM32公司主推的是HAL库的开发,标准库已经不再更新。通过STM32cubeMX的图形界面生成代码非常的方便。

一、程序框架的构想

1、STM32cubeMX 生成的代码与添加的应用代码分离;

2、利用 STM32cubeMX 重新生成代码,不影响应用代码;

3、应用代码的添加,移除与修改,不影响 cube 生成的代码;

4、代码架构方便阅读,编辑,修改与移植;

5、代码架构标准化,可以很方便的应用到产品开发中。

二、程序框架的实现

1、新增 MyApplication 文件夹,放置 4 个标准 c 文件,分别是公共文件,回调文件,系统文件, 用户初始化文件,后续应用代码均放在此文件夹;

 2、新增 MyApplication.h 文件,包含所有用户代码的头文件与外设头文件,调整外设或用户文件, 只需要调整此文件内的相应头文件即可;

3、main.c 文件标准化。

三 、MyApplication.h

#ifndef __MyApplication_H__
#define __MyApplication_H__

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

#include "stdio.h"
#include "stdlib.h"
#include "System.h"
#include "Public.h"
#include "MyInit.h"
#endif
/********************************************************
  End Of File
********************************************************/

1、此文件放置于 main.c 与应用代码文件中,作为头文件的集合;

2、更改处理器外设或应用代码,此文件需要相应的增加或删除相应的头文件。

四 、main.c 文件

1、添加头文件集合

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "MyApplication.h"
/* USER CODE END Includes */

2、添加用户初始化函数

  /* USER CODE BEGIN 2 */
  MyInit.Peripheral_Set();	
  /* USER CODE END 2 */

3、标准化主循环

 /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    System.Run();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4、标准化错误处理函数

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  System.Error_Handler();
  /* USER CODE END Error_Handler_Debug */
}

5、标准化断言失败处理函数

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
	System.Assert_Failed();
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

五 、system 文件

1、头文件

//定义结构体类型
typedef struct
{
	void (*Run)(void);
	void (*Error_Handler)(void);
	void (*Assert_Failed)(void);
} System_t;

/* extern variables-----------------------------------------------------------*/
extern System_t  System;
/* extern function prototypes-------------------------------------------------*/

主要定义结构体类型 System_t,包含 3 个函数指针,分别为函数运行,系统错误处理,断言失败 处理,被 main.c 文件调用。

2、源文件

/* Private variables----------------------------------------------------------*/
static void Run(void); 
static void Error_Handler(void);
static void Assert_Failed(void);
	
/* Public variables-----------------------------------------------------------*/
System_t System = 
{
	Run,
	Error_Handler,
	Assert_Failed
};

        主要定义结构体 System 以及 3 个函数,并将 3 个函数的名称(首地址)赋值给 System 结构体,完成结构体的初始化。 如此一来,main.c 文件可以通过 System 结构体的函数指针调用 System.c 文件的 3 个函数了。

Run 函数:用户应用代码;

Error_Hander 函数:系统错误处理代码;

Asset_Failed 函数: 断言失败处理代码

六 、Run 函数

static void Run()
{
	//初始化时,LED1,LED2,LED3均亮灯
	//HAL_GPIO_TogglePin -> 取反GPIO输出状态
	//HAL_GPIO_WritePin  -> 设置GPIO输出状态
	//                      GPIO_PIN_SET   -> 输出高电平,灯亮
	//                      GPIO_PIN_RESET -> 输出低电平
	
	//延时500ms,LED1,LED2,LED3均灭灯
	HAL_Delay(500);
	HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); 
	HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
	HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
	
}

作为功能演示,简单的实现了 LED1 、LED2 、LED3间隔 1s 闪烁。

这样的全新的程序框架就非常的完美啦,在日后的编写和程序一直都带来了极大的便利。

详细的视频讲解,请关注B站UP:硬件家园,本博客只是供自己学习,复习使用。

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

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

相关文章

zabbix配置钉钉告警(附含钉钉告警脚本 · 实战亲测无任何问题)

🍁博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 文章目录 钉钉上操作(钉钉告警以关…

密码学新进展:基于同态加密的数据保护是否会成为未来的趋势?

第一章:引言 在今天这个数字时代,数据的重要性不断增加,已经成为了现代社会最宝贵的财富之一。各种机构和企业在日常运营中都会处理大量的数据,包括用户信息、财务数据、产品销售数据等。这些数据的安全性非常重要,因…

2.5 定点运算器的组成

学习目标: 具体包括以下几点: 了解定点运算器的基本概念和分类,包括定点运算器的分类、常见的定点运算器类型等;学习定点运算器的基本组成部分,包括输入/输出接口、寄存器、算术逻辑单元(ALU)、控制单元等&#xff0…

VS Code C++ 输出窗口中文乱码问题解决

VS Code C 输出窗口中文乱码问题解决 系统cmd终端乱码 的情况:原因解决方法:(仅针对cmd终端输出的情况)方法一:更改代码文件的编码方法二 :更改cmd默认终端的编码方式 系统cmd终端乱码 的情况: …

2023年的深度学习入门指南(10) = 前端同学如何进行chatgpt开发

2023年的深度学习入门指南(10) 前端同学如何进行chatgpt开发 在第二篇,我们使用openai的python库封装,搞得它有点像之前学习的PyTorch一样的库。这一节我们专门给它正下名,前端就是字面意义上的前端。 给gpt4写前端 下面我们写一个最土的…

“BIM+智慧工地”精准“数字化”变身智慧工程“管家”

用手机对着满载钢筋的卡车拍照,手指选定一下钢筋范围,几秒后,屏幕就能迅速识别车上有多少根钢筋——这是建筑产业数字化管理智慧工程的应用领域之一。 投资1.78亿元建设的贵州民航产教融合实训基地是集实践教学、社会培训、企业生产保障和科研…

学历与就业:我对“孔乙已长衫”现象的思考

一、你认为社会对于学历和职业之间的关系认知是怎样的? 在当前的社会中,学历往往被看作是一个人能否获得好工作的重要标准。许多用人单位更愿意录取拥有更高学历的求职者,因为他们通常具备更广阔的知识视野和更强的理论基础。然而&#xff0…

Presto之Left Join和Right Join的实现

一. 前言 我们知道,在Presto中,与inner join相比,left join会保留probe表(左表)的所有值,right join会保留build表(右表)的所有值。inner join的是实现在文章Presto之Hash Join 数据…

攻击者可以使用HTML和CSS隐藏“外部发件人”电子邮件警告

导语:研究人员近日证实,Microsoft Outlook等客户端向电子邮件收件人显示的“外部发件人”警告可能被发件人隐藏。 研究人员近日证实,Microsoft Outlook等客户端向电子邮件收件人显示的“外部发件人”警告可能被发件人隐藏。 事实证明&#x…

【数据结构】一篇带你彻底玩转 链表

文章目录 链表的概念及结构链表的分类链表接口的实现链表打印链表申请节点链表尾插链表头插链表尾删链表头删链表查找链表在指定位置之后插入数据链表删除指定位置之后的数据链表在指定位置之前插入数据链表删除指定位置之前的数据链表删除指定位置的数据链表的销毁 链表的概念…

总结835

学习目标: 4月(复习完高数18讲内容,背诵21篇短文,熟词僻义300词基础词) 学习内容: 暴力英语:熟练背诵《大独裁者》,最后默写。抄写今后要背诵的两篇文章。 高等数学:做…

机器视觉各开发语言对比以及选择

机器视觉主流开发语言主要有, 一.C#,占有率极高 市面主要以Halcon,visionpro,visionmaster,opencvsharp为主。 开发人员利用 C# 能够生成在 .NET 中运行的多种安全可靠的应用程序。 二.C++,Qt 市面主要以Halcon,visionpro,visionmaster,opencv为z主。 C++ 即已成为世界上…

Arduino学习笔记5

一.直流电机控制实验 1.源代码 int dianJiPin9;//定义数字9接口接电机驱动IN1的控制口void setup() {pinMode(dianJiPin,OUTPUT);//定义电机驱动IN1的控制口为输出接口 } void loop() {digitalWrite(dianJiPin,LOW);//关闭电机delay(1000);//延时digitalWrite(dianJiPin,HIGH…

基于protobuf构建grpc服务

一、protobuf介绍 protobuf是谷歌开源的一种数据格式,适合高性能,对响应速度有要求的数据传输场景。因为profobuf是二进制数据格式,需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。 优势: 序列…

【Unity-UGUI控件全面解析】| Text文本组件详解

🎬【Unity-UGUI控件全面解析】| Text文本组件详解一、组件介绍二、组件属性面板三、代码操作组件四、组件常用方法示例4.1 改变Text文本颜色4.2 文本换行问题4.3 空格自动换行问题4.4 逐字显示效果五、组件相关扩展使用5.1 文本描边组件(Outline)5.2 阴影组件(Shadow)5.3…

操作系统——操作系统逻辑结构

0.关注博主有更多知识 操作系统入门知识合集 目录 2.1操作系统的逻辑结构 思考题: 2.2CPU的态 思考题: 2.3中断机制 2.1操作系统的逻辑结构 操作系统的结构指的是操作系统的设计和实现思路,按照什么样的结构设计、实现。 操作系统的…

[java]云HIS:检验字典维护

术语解释: 1、最小剂量:并非指医生开处方时的最小剂量值,而是为了对应计量单位和剂量单位之间数量关系而设置的。 2、包装规格:是计价单位和计量单位之间换算的关系值,1个计价单位计价规格个计量单位。 药品单位之间的…

【三十天精通Vue 3】第二十一天 Vue 3的安全性详解

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3 文章目录 引言一、Vue 3 中的安全问题1.1 前端安全问题概述1.2 Vue 3 中的安…

浅谈Golang等多种语言转数组成字符串

目录 Python 一维列表转字符串 二维列表转字符串 多维列表转字符串 Golang 一维数组的遍历打印 二维数组的遍历打印 Java 一维容器的直接打印 二维容器的直接打印 普通数组的转化 C 一维容器的遍历 1. to_string() 2. stringstream 二维容器的遍历 简要小结 …

【Python--高级教程】

高级教程 1.正则表达式re.compile()re.match()函数re.search()函数re.search()函数与re.match()函数的区别group(num) 或 groups()检索和替换re.sub()替换函数中的re.sub可以是一个函数findAll()方法re.finditer()方法re.split()regex修饰符正则表达式模式 2.CGI编程什么是CGI网…