嵌入式开发六:新建工程—寄存器版

news2024/10/7 4:31:16

     通过前面的学习,我们对 STM32 有了个比较清晰的了解,本次我们将讲解新建寄存器库版本 MDK 工程的详细步骤。后期我们基于固件库开发,借助Keil5的环境配置助手界面RTE,不需要进行文件移植,本节的寄存器版本,作为了解内容,学习整个新工程的创建过程。

目录

一、新建一个工程框架

二、添加文件

 2.1 添加启动代码

 2.2 添加SYSTEM文件 

 2.3 在工程中建立同名称的分组

三、魔术棒设置

3.1.设置Target选项卡

3.2.设置Output选项卡

3.3.设置Listing选项卡

3.4.设置C/C+ +选项卡

3.5.设置Debug选项卡

3.6.设置Utilities选项卡

四、在test.c中编写代码,编译


一、新建一个工程框架

       首先,打开 MDK(以下将 MDK5 简称为 MDK)软件。然后点击 Project→New uVision Project 如图 3.2.1 所示:

弹出如图 3.2.2 所示界面:

      在桌面新建一个 TEST 的文件夹,然后在 TEST 文件夹里面新建 USER 文件夹,将工程名字设为 test,保存在这个 USER 文件夹里面,之后,弹出选择器件的对话框,如图 3.2.3 所示。 因为 ALIENTEK 探索者 STM32F4 开发板所使用的 STM32 型号为 STM32F407ZGT6,所以在 这里我们选择 STMicroelectronics→STM32F4 Series→STM32F407→STM32F407ZGT6(如果使 用的是其他系列的芯片,选择相应的型号就可以了,特别注意:一定要安装对应的器件 pack 才会显示这些内容哦!!(我使用的是Keil.STM32F4xx_DFP.1.0.8.pack 这个安装包)

点击 OK,MDK 会弹出 Manage Run-Time Environment 对话框,如图 3.2.4 所示:

这是 MDK5 新增的一个功能,在这个界面,我们可以添加自己需要的组件包括:内核文件(CORE)、启动文件(startup)、以及需要用到的外设,从而方便新建工程,(后面的库函数版本将使用这种方式创建工程,更加方便快捷,如果使用这种方式后,会自动生成一个RTE文件夹)不过这里我们不做介绍。所以在图 3.2.4 所示界面,我们直接点击 Cancel,即可, 得到如图 3.2.5 所示界面:

到这里,我们还只是建了一个框架,还需要添加启动代码,以及.c 文件等,接下来就是添加文件 

二、添加文件

启动代码:启动代码是一段和硬件相关的汇编代码。是必不可少的!这代码主要作用如 下:1、堆栈(SP)的初始化;2、初始化程序计数器(PC);3、设置向量表异常事件的入口地 址;4、调用 main 函数。

 2.1 添加启动代码

       ST 公司为 STM32F40x 和 STM32F41x 系列的 STM32F4 提供了一个共同的启动文件,名字为:startup_stm32f40_41xxx.s。我们开发板使用的是 STM32F407ZGT6,属于 STM32F40x 系列 里面的,所以直接使 startup_stm32f40_41xxx.s 这个启动文件即可。不过这个启动文件,我们做 了一点点修改,具体是 Reset_Handler 函数,该函数修改后代码如下:

这段代码,我们主要加入了开启 STM32F4 硬件 FPU 的代码,以使能 STM32F4 的浮点运 算单元。其中,0xE000ED88 就是协处理器控制寄存器(CPACR)的地址,该寄存器的第 20~23位用来控制是否支持浮点运算,这里我们全设置为 1,以支持浮点运算。另外,寄存器版本,我们还屏蔽了 SystemInit 函数的调用,如果是库函数版本,可以取消这个函数的注释, 并在外部实现SystemInit 函数。

      特别注意:我们在汇编代码里面使能了 FPU,所以在 MDK 里面,我们也要设置使用 FPU, 否则可能代码会无法运行,设置方法如下:选择 Options for Target ‘Target1’,打开 Target 选 项卡,在 Code Generation 里面,选择 Use FPU,如图 3.2.6 所示:

 这样,MDK 编译生成的代码,就可以直接使用硬件 FPU 了,其实就 2 个步骤:1,设置 CPACR 寄存器 20~23 位全为 1,使能硬件 FPU。2,设置 MDK 选型,选择 Use FPU。另外, 图 3.2.6 中,MDK 默认 STM32F4 外部晶振为 12M,我们板子用的 8M,所以这里设置为 8Mhz。至此,启动文件修改完成设置完成。接下来把这个 startup_stm32f40_41xxx.s 拷贝到刚刚新建的 USER 文件夹里面。 在图 3.2.5 中,我们找到 Target1→Source Group1→双击→设置打开文件类型为 Asm Source file→选择 startup_stm32f40_41xxx.s→点击 Add,如图 3.2.7 所示:

这里看到的 2 个文件夹:Listings 和 Objects,是 MDK5 自行创建的,用于保存编译过程中 生成的一些文件,后续会介绍。添加完后,我们得到如图 3.2.8 所示的界面:

     至此,我们就可以开始编写自己的代码了。不过,在此之前,我们先来做两件事:第一件, 先编译一下,看看什么情况?编译后如图 3.2.9 所示:

 图 3.2.9 中 1 处为编译当前目标按钮;2 处为全部重新编译按钮(工程大的时候,编译耗时 较久,建议少用)。出错和警告信息在下面的 Bulilt Output 对话框中提示出来了。因为工程中没 有 main 函数,所以报错了。 接下来,第二件事,让我们看看存放工程的文件夹有什么变化?打开我们刚刚建立的TEST\USER 文件夹,可以看到里面多了 2 个文件夹:Listings 和 Objects,如图 3.2.10 所示:

       在 USER 文件夹下,startup_stm32f40_41xxx.s(启动文件)和 test.uvprojx(MDK5 工程文 件)是我们必须用到的 2 个文件,然后 Listings 和 Objects 文件夹是 MDK5 自动生成的,如果打开 Listings 和 Objects 文件夹,就可以看到里面多了一些文件,这就是 MDK 编译过程产生的 中间文件,如果工程量大,产生的文件更多(多的可达 100 MB 以上!!)。 MDK5.14 已经默认将这些文件生成在了 Listings 和 Objects 文件夹里面,但是 MDK5.11A 及之前版本是不会自动生成这两个文件夹的,所有中间文件都是生成在工程同面目录下,也就 是 USER 文件夹下,这样会显得比较混乱。 这里,我们不用 MDK5 自己生成的这两个文件夹来存放中间文件,而是在 TEST 目录下新 建一个新的 OBJ 文件夹来存放这些中间文件。这样,USER 文件夹专门用来存放启动文件 (startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件,而 OBJ 则用来存放 这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面)。然后把 Listings 和 Objects 文件夹里面的东西全部移到 OBJ 文件夹下(当然要先关闭 MDK 软件)。整理后效果 如图 3.2.11 所示: 

 2.2 添加SYSTEM文件 

       由于上面我们还没有任何代码在工程里面,这里我们把系统代码 COPY 过来(即 SYSTEM 文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到,不过不要拷贝错了!不要把库函数代码的系统文件夹拷贝到寄存器代码里面用,反之亦然!这些代码在任何 STM32F40x/STM32F41x 的芯片上都是通用的,可以用于快速构建自己的工程,后面会有详细介绍)。完了之后,TEST 文件夹下的文件如图 3.2.12 所示:

 2.3 在工程中建立同名称的分组

      接下来,便是在工程中建立两个同名称的分组:USER、SYSTEM,我们在 USER 文件夹下面找到 test.uvproj,打开它,然后在 Target 目录树上点击右键 →Manage Project Items,弹出如图 3.2.13 所示对话框:

      在上面对话框的中间栏,点新建(用红圈标出)按钮(也可以通过双击下面的空白处实现), 新建 USER 和 SYSTEM 两个组。然后点击 Add Files 按钮,把 SYSTEM 文件夹三个子文件夹里 面的:sys.c、usart.c、delay.c 加入到 SYSTEM 组中。注意:此时 USER 组下还是没有任何文件,得到如图 3.2.14 所示的界面:

点击 OK,退出该界面返回 IDE。这时,我们在 Target1 树下发现多了 2 个组名,就是我们

刚刚新建的 2 个组。如图 3.2.15 所示:

接着,我们新建一个 test.c 文件,并保存在 USER 文件夹下(相当于main.c)。得到如图 3.2.16 所示的界面: 

三、魔术棒设置

      为避免编写代码和编译报错,我们需要通过魔术棒对 MDK 工程进行相关设置。在 MDK 主界面,点击: (魔术棒图标,即 Options for Target 按钮),进入工程设置对话框,我们将进行如下几个选项卡的设置。

3.1.设置Target选项卡

      在魔术棒→Target 选项卡里面,我们进行如图所示设置,下图中,我们设置芯片所使用的外部晶振频率为 8Mhz,选择 ARM Compiler 版本为:Use default compiler version 5(即 AC5 编译器)。

3.2.设置Output选项卡

         在魔术棒→Output 选项卡里面,进行如图 所示设置:

注意,我们勾选:Browse Information,用于输出浏览信息,这样就可以使用 go to definition 查看函数/变量的定义,对我们后续调试代码比较有帮助,如果不需要调试代码,则可以去掉这个勾选,以提高编译速度。


3.3.设置Listing选项卡

       在魔术棒→Listing 选项卡里面,进行如图 6.1.4.3 所示设置:

经过 Output 和 Listing 这两步设置,原来存储在 Objects 和 Listings 文件夹的内容(中间文 件)就都改为输出到 OBJ文件夹了。


3.4.设置C/C+ +选项卡

在魔术棒→C/C++选项卡里面,进行如图3.2.21 所示设置:因为引入的头文件模块,都需要包含路径,不然编译器无法找到头文件,自然会报错。

    在1处设置了全局宏定义:STM32F40_41xxx,用于定义所用 STM32 型号,在 stm32f4xx.h 里 面会用到该宏定义。 在2处设置了优化等级为-O0,可以得到最好的调试效果,当然为了提高优化效果提升性能 并降低代码量,可以设置-O1~-O3,数字越大效果越明显,不过也越容易出问题。注意:当使用 AC6 编译器的时候,这里推荐默认使用-O1 优化。 勾选 C99 模式,即使用 C99 C 语言标准。 图中 3 处,One ELF Section per Function 主要是用来对冗余函数的优化。通过这个选项, 可以在最后生成的二进制文件中将冗余函数排除掉,以便最大程度地优化最后生成的二进制代 码,所以,我们一般勾选上这个,这样可以减少整个程序的代码量。在4处,我们可以进行头文件包含路径设置,点击此按钮,进行如图所示设置:在 Include Paths 处(4 处),点击 5 处的按钮。在弹出的对话框中加入 SYSTEM 文件 夹下的 3 个文件夹名字,把这几个路径都加进去(此操作即加入编译器的头文件包含路径,后 面会经常用到)。如图 3.2.22 所示:

      至此,我们一个完整的 STM32F4 开发工程在 MDK5 下建立了。接下来我们就可以进行调试的配置,然后进行代码下载和验证调试了。


3.5.设置Debug选项卡

在魔术棒→Debug 选项卡里面,进行如图 6.1.4.7 所示设置:

图中,我们选择使用:CMSIS-DAP 仿真器,使用 SW 模式,并设置最大时钟频率为 10Mhz, 以得到最高下载速度。当我们将仿真器和开发板连接好,并给开发板供电以后,仿真器就会找 到开发板芯片,并在 SW Device 窗口显示芯片的 IDCODE、Device Name 等信息(图中⑤处), 当无法找到时,请检查供电和仿真器连接状况。


3.6.设置Utilities选项卡

在魔术棒→Debug 选项卡里面,进行如图 6.1.4.8 所示设置:

这里 MDK5 会根据我们新建工程时选择的目标器件,自动设置 flash 算法。我们使用的是 STM32F407ZGT6,FLASH 容量为 1M 字节,所以 Programming Algorithm 里面默认会有 1M 型 号的 STM32F4xx FLASH 算法。特别提醒:这里的 1M flash 算法,不仅仅针对 1M 容量的 STM32F4,对于小于 1M FLASH 的型号,也是采用这个 flash 算法的。最后,选中 Reset and Run 选项,以实现在编程后自动运行,其他默认设置即可。设置完成之后,如图所示。在设置完之后,点击 OK,然后再点击 OK,回到 IDE 界面。


四、在test.c中编写代码,编译

至此,我们就可以开始编写我们自己的代码了。我们在 test.c 文件里面输入如下代码:

#include "sys.h"
#include "usart.h" 
#include "delay.h" 
int main(void)
{ 
   uint8_t =0;
   Stm32_Clock_Init(336,8,2,7);//初始化时钟为 168Mhz
   delay_init(168); //初始化延时函数
   uart_init(84,115200); //串口初始化为 115200
   while(1)
   {
      printf("t:%d\r\n",t);   //需要重定向到串口
      delay_ms(500);
     t++;
   }
}

      进行编译的话,下载到开发板,我们打开串口调试助手选择 COM3(得根据你的实际情况选择),设置波特率为 115200,会发现从探索者 STM32F4 开发板发回来的信息,如图 4.1.8 所示:

       接收到的数据和我们期望的是一样的,证明程序没有问题。至此,说明我们下载代码成功 了,并且从硬件上验证了我们代码的正确性。至此,新建寄存器版本 MDK 工程完成。

      可以看出,寄存器版本的工程创建起来还算简单,移植的文件比较少,但是到了库函数就会有大量需要移植的文件,这种方式配置文件环境便不合适,下一节我们正式讲解如何利用RTE助手配置库函数版本工程环境,将会大大降低复杂度。

     以上便是STM32 新建工程—寄存器版的全部内容,如有兴趣,感谢点赞、关注、收藏,若有不正地方,还请各位大佬多多指教!

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

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

相关文章

测试通过!X-Argus、X-Gorgon、X-Medusa和X-Helions

算法分析测试 Host:api5-normal-sinfonlinea.fqnovel.com Cookie:install_id2821771262445211; ttreq1$eb27d336c987581d9ed1b36c48cab2c7bcbc7305; d_ticket38b3fb964c1b4c5955565dc0f91cfcf64df74; odin_tte25761a2638b499c0bf8840c9857e43a17899df1213ba33153a266bbddf47b5…

CSS盒子模型 (盒子模型 下)

(大家好,今天我们将继续来学习CSS的相关知识,大家可以在评论区进行互动答疑哦~加油!💕) 目录 1.4 表格的细线边框 1.5 边框会影响盒子实际大小 1.6 内边距(padding) 案例:新浪微博选框栏…

口才训练:如何用声音和语言展现自我魅力

口才训练:如何用声音和语言展现自我魅力 这里有一篇1270字左右的文章,主要介绍如何用声音和语言来展现自我魅力: 口才训练是提升个人魅力的重要途径之一。魅力不仅取决于外表,更重要的是声音和语言的运用。良好的语言表达能力可以…

CMakeLists.txt语法规则:部分常用命令说明一

一. 简介 前一篇文章简单介绍了CMakeLists.txt 简单的语法。文章如下: CMakeLists.txt 简单的语法介绍-CSDN博客 接下来对 CMakeLists.txt语法规则进行具体的学习。本文具体学习 CMakeLists.txt语法规则中常用的命令。 二. CMakeLists.txt语法规则:…

小程序账号设置以及request请求的封装

一般开发在小程序时,都会有测试版和正式版,这样在开发时会比较方便。 在开发时。产品经理都会给到测试账号和正式账号,后端给的接口也都会有测试环境用到的接口和正式环境用到的接口。 这里讲一讲我这边如何去做的。 1.在更目录随便命名一…

Ubuntu20安装torch1.13和pytorch_geometric2.3.0(对应cuda11.6)

在torch下载页面搜索1.13https://pytorch.org/get-started/previous-versions/,wheel安装方式(激活conda虚拟环境) pip install torch1.13.0cu116 torchvision0.14.0cu116 torchaudio0.13.0 --extra-index-url https://download.pytorch.org…

“100先生”逢跌加仓

原创 | 刘教链 BTC(比特币)从前日创下的局部低点56.5k持续修复至59k上方,距离重回6万刀仅有半步之遥。 群里有群友还在等25k。还有朋友发来消息问,这次是不是有机会跌回15k? 躺下睡一觉。梦里会有的。 就在前两天ETF们…

时间复杂度空间复杂度 力扣:转轮数组,消失的数字

1. 算法效率 如何衡量一个算法的好坏?一般是从时间和空间的维度来讨论复杂度,但是现在由于计算机行业发展迅速,所以现在并不怎么在乎空间复杂度了下面例子中,斐波那契看上去很简洁,但是复杂度未必如此 long long Fib…

BAPI_PR_CHANGE how to add account assignment information for service line,如何解决?

🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&…

数据结构(十)----图

目录 一.图的概念 1.图的定义 2.图的类别 3.图的性质 4.几种特殊形态的图 二.图的存储结构 1.邻接矩阵(顺序存储) 2.邻接表(顺序链式存储) 3.十字链表 4.邻接多重表 四.图的遍历 1.广度优先遍历(BFS&#…

Elasticsearch 数据聚合

Bucket聚合(桶聚合) 对文档做分组,aggs 按照文档字段值或日期进行分组,能参与分词的字段不能做聚合,如text类型的字段 例如:根据城市名称做聚合,也就是城市名称对数据进行分组统计。可以加qu…

Python数据分析案例43——Fama-French回归模型资产定价(三因子/五因子)

案例背景 最近看到要做三因子模型的同学还挺多的,就是所谓的Fama-French回归模型,也就是CAMP资本资产定价模型的升级版,然后后面还升级为了五因子模型。 看起来眼花缭乱,其实抛开金融资产定价的背景,从机器学习角度来…

2024年3月Scratch图形化编程等级考试(三级)真题试卷

2024年3月Scratch图形化编程等级考试(三级)真题试卷 选择题 第 1 题 Scratch运行程序后,角色一定不会说出的数字是?( ) A.2 B.4 C.6 D.8 第 2 题 Scratch角色初始位置如下图所示,右图…

Spring Boot与OpenCV:融合机器学习的智能图像与视频处理平台

🧑 作者简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

spring框架学习记录(2)

文章目录 注解开发bean相关注解开发定义bean纯注解开发纯注解开发中bean的管理 依赖注入相关依赖注入第三方bean管理第三方bean依赖注入 AOP(Aspect Oriented Programming)面向切面编程AOP简介AOP核心概念AOP工作流程AOP切入点表达式通知类型AOP通知获取数据 注解开发 bean相关…

大语言模型中的第一性原理:Scaling laws

大语言模型的尺度定律在大语言模型的训练过程中起到了非常重要的作用。即使读者不参与大语言模型的训练过程,但了解大语言模型的尺度定律仍然是很重要的,因为它能帮助我们更好的理解未来大语言模型的发展路径。 1. 什么是尺度定律 尺度定律&#xff08…

现代循环神经网络(GRU、LSTM)(Pytorch 14)

一 简介 前一章中我们介绍了循环神经网络的基础知识,这种网络 可以更好地处理序列数据。我们在文本数据上实现 了基于循环神经网络的语言模型,但是对于当今各种各样的序列学习问题,这些技术可能并不够用。 例如,循环神经网络在…

【错题集-编程题】十字爆破(预处理 + 模拟)

牛客对于题目链接:十字爆破 (nowcoder.com) 一、分析题目 暴力模拟会超时。 预处理,先把每一行以及每一列的和存起来。 模拟即可,但是由于数据量过⼤,我们可以提前把每⼀⾏以及每⼀列的和存起来,⽅便统计总和。 二、代…

(centos)yum安装mysql8.4

1.MySQL官方已经提供了适用于不同Linux发行版的预构建软件包,包括适用于CentOS的Yum Repository MySQL :: MySQL Community Downloads 2.在/usr/local文件夹下创建mysql文件夹,将下载的rpm文件放到目录下 3.执行安装命令 yum install mysql-community-…

思科防火墙查如何查看现有ipsec隧道信息

环境: 思科ASA5555 问题描述: 思科防火墙查如何看现有ipsec隧道信息 解决方案: 1.进入特权模式: enable 查看isakmp信息 show crypto isakmp sa2.查看ipsec信息 show crypto ipsec sa上述命令将显示当前的ISAKMP安全关联…