手把手教你F103工程文件的创建并且通过protesu仿真验证创建工程文件的正确性(低成本)

news2024/7/3 19:55:43

目录

一、新建工程文件夹

二、新建一个工程框架

三、添加文件

四、仿真验证

五、仿真调试中遇到的问题并解决


一、新建工程文件夹

新建工程文件夹分为 2 个步骤:1,新建工程文件夹;2,拷贝工程相关文件。

1.新建工程文件

        首先我们在桌面新建一个工程根目录文件夹,后续的工程文件都将在这个文件夹里建立, 我们把这个文件夹重命名为:寄存器版本,如下图所示:

         为了让工程的文件目录结构更加清晰易懂,我们会在工程根目录文件夹下建立以下几个文 件夹,每个文件夹名称及其作用如下表所示:

 新建完成以后,最后得到我们的工程根目录文件夹如下图所示:

         工程根目录及其相关文件夹新建好以后,我们需要拷贝一些工程相关文件过来(主要是在 Drivers 文件夹里面),以便等下的新建工程需要。

2. 拷贝工程相关文件

        接下来我们需要往刚才新建的文件夹里边拷贝一些文件。

Drivers 文件夹

该文件夹用于存放与硬件相关的驱动层文件,一般包括如下表所示的三个文件夹:

         BSP 文件夹,用于存放一些驱动文件,如:LED、蜂鸣器、按键等。 

        CMSIS 文件夹,用于存放 CMSIS 底层代码(ARM 和 ST 提供),如:启动文件(.s 文件)、 stm32f1xx.h 等各种头文件。该文件夹我们可以直接从 STM32CubeF1 固件包里面拷贝,不过由于固件包里面的 CMISIS 兼容 了太多芯片,导致非常大(100 多 MB),因此我们根据实际情况,对其进行了大幅精简,精简 后的 CMSIS 文件夹大小为 1MB 左右。

        SYSTEM 文件夹,用于存放系统级核心驱动代码

        执行完以上操作后,Drivers 文件夹最终结构如下图所示;

 Middlewares 文件夹

         该文件夹用于存放第三方提供的中间层代码(组件/Lib 等)

Output 文件夹

        该文件夹用于存放编译器编译工程输出的中间文件,比如:.hex、.bin、.o 文件等等。这里 不需要操作,后面只需要在 MDK 里面设置该文件夹为编译过程中间文件的存放文件夹就行

Projects 文件夹

        该文件夹用于存放编译器(MDK、IAR 等)工程文件,我们主要用 MDK,为了方便区分, 我们在该文件夹下新建:MDK-ARM 文件夹,用于存放 MDK 的工程文件,

User 文件夹

        该文件夹用于存放用户编写的代码,如:main.c 等。

二、新建一个工程框架

        首先,打开 MDK 软件。然后点击 Project→New uVision Project 如下图所示

        然后弹出工程命名和保存的操作窗口,我们将工程文件保存路径设置在上一节新建的工程 文件夹内,具体路径为:桌面→寄存器版本,→Projects→MDK-ARM, 工程名字我们取:zy_f103,最后点击保存即可。具体操作窗口下图所示:

         之后,弹出器件选择对话框,如图 6.1.2.3 所示。因为战舰开发板所使用的 STM32 型号为 STM32F103ZET6,所以我们选择:STMicroelectronics→STM32F1 Series→STM32F103→ STM32F103ZE(如果使用的是其他系列的芯片,选择相应的型号就可以了。如下图所示:

 点击 OK,MDK 会弹出 Manage Run-Time Environment 对话框,我们关闭就行了

接下来进入KIEL5界面

         此时,我们打开 MDK-ARM 文件夹,会看到 MDK 在该文件夹下自动创建了 3 个文件夹 (DebugConfig、Listings 和 Objects),这三个文件夹的作用如下表所示:

         编译过程产生的链接列表、调试信息、预览、lib 等文件,统称为中间文件。为了统一管理, 方便使用,我们会把输出在 Listings 和 Objects 文件夹的内容,统一改为输出到 Output 文件夹 (通过魔术棒设置),我们先把 MDK 自动生成的这两个文件夹(Listings 和 Objects)删除。

三、添加文件

本节将分 3 个步骤:1,设置工程名和分组名;2,添加启动文件;3,添加 SYSTEM 源码。

1.设置工程名和分组名

        在 Project→Target 上右键,选择 Manage Project Items…(方法一)或在菜单栏点击品字形 红绿白图标(方法二)进入工程管理界面,如下图所示:

         在工程管理界面,我们可以执行设置工程名字(Project Targets)、分组名字(Groups)以 及添加每个分组的文件(Files)等操作。我们设置工程名字为:Template,并设置四个分组: Startup(存放启动文件)、User(存放 main.c 等用户代码)、Drivers/SYSTEM(存放系统级驱 动代码)、Readme(存放工程说明文件),如下图所示:

  

         设置好之后,我们点击 OK,回到 MDK 主界面,可以看到我们设置的工程名和分组名如下图所示:

2.添加启动文件

        启动文件(.s 文件)包含 STM32 的启动代码,其主要作用包括:1、堆栈(SP)的初始化; 2、初始化程序计数器(PC);3、设置向量表异常事件的入口地址;4、调用 main 函数等,是每 个工程必不可少的一个文件。

该文件由 ST 官方提供,对于 STM32F103 来说有 4 个启动文件可选,如下表所示:

         启动文件存放在 STM32CubeF1 软件包的:Drivers→CMSIS→Device→ST→STM32F1xx→ Source→Templates→arm 文件夹下。因为我们开发板使用的是 STM32F103ZET6,对应的启动文 件为:startup_stm32f103xe.s,为了节省空间,在精简版 CMSIS 文件夹里面我们把其他启动文件 都删了。而且,为了更好的匹配寄存器版本代码,我们对 startup_stm32f103xe.s 做了 2 处修改:

1.我们用不到编译器的内存管理函数,为节省内存,将 Heap_Size 改成 0,源码如下:

;未用到编译器自带的内存管理(malloc,free 等),设置 Heap_Szie 为 0
Heap_Size EQU 0x00000000

2,寄存器代码不需要调用 SystemInit 函数,因此修改 Reset_Handler 函数,去掉 SystemInit 调用,源码如下:

Reset_Handler PROC
 EXPORT Reset_Handler [WEAK]
 IMPORT __main
 ;寄存器版本代码,因为没有用到 SystemInit 函数,所以注释掉以下代码为防止报错!
 ;HAL 库版本代码,建议加上这里(提供 SystemInit 函数),以初始化 stm32 时钟等。
 ;IMPORT SystemInit
 ;LDR R0, =SystemInit
 ;BLX R0
 LDR R0, =__main
 BX R0
 ENDP

这了我们使用方法 1 添加(路径:寄存器版本\Drivers\CMSIS\ Device\ST\STM32F1xx\Source\Templates\arm),

 上图中,我们也可以点击 Add 按钮进行文件添加。添加完后,点击 Close,完成启动文件 添加,得到工程分组如下图所示。

 3. 添加 SYSTEM 源码

这里我们在工程管理界面(方法 2)进行 SYSTEM 源码添加。点击:管理按钮,进入工程 管理界面,选中 Drivers/SYSTEM 分组,然后点击:Add Files,进入文件添加对话框,依次添加delay.c、sys.c 和 usart.c 到该分组下,

 添加完成以后如下:

接下来我们编写主函数,并且添加到user中,如下:

编译程序,0 error 0warnning

 四、仿真验证

1.我们新建一个proteus文件,并且连接如下图所示:

2.双击芯片,并且将程序下载进去,调试

由串口输出的值来看,我们所创建的工程是正确的。 

 五、仿真调试中遇到的问题并解决

 解决办法:点击Design,再点击Power Rail Configuration,将VVC添加过去

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

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

相关文章

【04】STM32·HAL库开发-MDK5使用技巧 |文本美化 | 代码编辑技巧 | 查找与替换技巧 | 编译问题定位 | 窗口视图初始化

目录 1.文本美化(熟悉)1.1编辑器设置1.2字体和颜色设置1.3用户关键字设置1.4代码提示&语法检测1.5global.prop文件妙用 2.代码编辑技巧(熟悉)2.1Tab键的妙用2.2快速定位函数或变量被定义的地方2.3快速注释&快速取消注释 3…

python面向对象操作2(速通版)

目录 一、私有和公有属性的定义和使用 1.公有属性定义和使用 2.私有属性 二、继承 1.应用 2.子类不能用父类的私有方法 3.子类初始化父类 4.子类重写和调用父类方法 5.多层继承 6.多层继承-初始化过程 7.多继承基本格式 8.多层多继承时的初始化问题 9.多继承初始化…

云原生Docker Cgroups资源控制操作

资源控制 Docker 通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如…

Node服务器-express框架

1 Express认识初体验 2 Express中间件使用 3 Express请求和响应 4 Express路由的使用 5 Express的错误处理 6 Express的源码解析 一、手动创建express的过程: 1、在项目文件的根目录创建package.json文件 npm init 2、下载express npm install express 3、基本…

kafka3

分区副本机制 kafka 从 0.8.0 版本开始引入了分区副本;引入了数据冗余 用CAP理论来说,就是通过副本及副本leader动态选举机制提高了kafka的 分区容错性和可用性 但从而也带来了数据一致性的巨大困难! 6.6.2分区副本的数据一致性困难 kaf…

多模态学习

什么是多模态学习? 模态 模态是指一些表达或感知事物的方式,每一种信息的来源或者形式,都可以称为一种模态 视频图像文本音频 多模态 多模态即是从多个模态表达或感知事物 多模态学习 从多种模态的数据中学习并且提升自身的算法 多…

【k8s 系列】k8s 学习三,docker回顾,k8s 起航

k8s 逐渐已经作为一个程序员不得不学的技术,尤其是做云原生的兄弟们,若你会,那么还是挺难的 学习 k8s ,实践尤为重要,如果身边有自己公司就是做云的,那么云服务器倒是不用担心,若不是&#xff…

IMX6ULL PHY 芯片驱动

前言 之前使用 IMX6ULL 开发板时遇到过 nfs 挂载不上的问题,当时是通过更换官方新版 kernel 解决的,参考《挂载 nfs 文件系统》。 今天,使用自己编译的 kernel 又遇到了该问题,第二次遇到了,该正面解决了。 NFS 挂载…

18JS09——作用域

作用域 一、作用域1、作用域 二、变量的作用域1、变量作用域的分类2、全局变量3、局部变量4、全局变量和局部变量区别 三、作用域链 目标: 1、作用域 2、变量的作用域 3、作用域链 一、作用域 1、作用域 通常来说,一段程序代码中所用到的名字并不总是有…

python基础----06-----文件读写追加操作

一 文件编码概念 思考:计算机只能识别: 0和1,那么我们丰富的文本文件是如何被计算机识别,并存储在硬盘中呢? 答案:使用编码技术(密码本)将内容翻译成0和1存入。 常见编码有UTF8,gbk等等。不同的编码,将内…

vulnhub靶场之DC-3渗透教程(Joomla CMS)

目录 0x01靶机概述 0x02靶场环境搭建 0x03主机发现 0x04靶场渗透过程 ​ 0x05靶机提权 0x06渗透实验总结 0x01靶机概述 靶机基本信息: 靶机下载链接https://download.vulnhub.com/dc/DC-3-2.zip作者DCAU发布日期2020年4月25日难度中等 0x02靶场环…

【Flink】DataStream API使用之输出算子(Sink)

输出算子(Sink) Flink作为数据处理框架,最终还是需要把计算处理的结果写入到外部存储,为外部应用提供支持。Flink提供了很多方式输出到外部系统。 1. 连接外部系统 在Flink中我们可以在各种Fuction中处理输出到外部系统&#xf…

C#读写参数到APP.Config

C#读写参数到APP.Config 介绍程序Demo常见错误 介绍 系统在开发时,可能需要设置默认参数,比如数据库的链接参数,某个参数的默认数据等等。对于这些数据,可直接在app.config中读取。 在读写时,需要先了解configuratio…

echo命令在Unix中的作用以及其常见用法

在Unix系统中,"echo"是一个常用的命令,用于在终端或脚本中输出文本。它可以将指定的字符串或变量的值打印到标准输出,从而向用户提供信息或进行调试。 本文将详细介绍"echo"命令在Unix中的作用以及其常见用法。 基本语法…

Keras-3-实例1-二分类问题

1. 二分类问题 1.1 IMDB 数据集加载 IMDB 包含5w条严重两极分化的评论,数据集被分为 2.5w 训练数据 和 2.5w 测试数据,训练集和测试集中的正面和负面评论占比都是50% from keras.datasets import imdb(train_data, train_labels), (test_data, test_l…

UE5 Chaos破碎系统学习1

在UE5中,Chaos破碎系统被直接进行了整合,本篇文章就来讲讲chaos的基础使用。 1.基础破碎 1.首先选中需要进行破碎的模型,例如这里选择一个Box,然后切换至Fracture Mode(破碎模式): 2.点击右侧…

JAVA实现打字练习软件

转眼已经学了一学期的java了,老师让我们根据所学知识点写一个打字练习软件的综合练习。一开始我也不是很有思路,我找了一下发现csdn上关于这个小项目的代码也不算很多,所以我最后自己在csdn查了一些资料,写了这么一个简略版本的打…

【C++】——list的介绍及模拟实现

文章目录 1. 前言2. list的介绍3. list的常用接口3.1 list的构造函数3.2 iterator的使用3.3 list的空间管理3.4 list的结点访问3.5 list的增删查改 4. list迭代器失效的问题5. list模拟实现6. list与vector的对比7. 结尾 1. 前言 我们之前已经学习了string和vector&#xff0c…

Remix IDE已支持Sui Move在线开发

网页版Remix IDE与WELLDONE Code插件结合,让您无需本地设置或安装即可开始构建Sui应用程序。 不熟悉Sui的构建者可能想在正式配置开发环境之前,浅尝一下构建Sui应用程序。Remix IDE与WELLDONE Code插件组合,即可帮助构建者实现从浏览器窗口开…

JavaScript函数的增强知识

函数属性和arguments以及剩余参数 函数属性name与length ◼ 我们知道JavaScript中函数也是一个对象,那么对象中就可以有属性和方法。 ◼ 属性name:一个函数的名词我们可以通过name来访问; // 自定义属性foo.message "Hello Foo"…