嵌入式入门实践——编写简单STM32程序

article/2025/11/9 18:11:58

嵌入式入门——编写简单STM32程序

目录

  • 嵌入式入门——编写简单STM32程序
    • 一、环境配置
      • 1、安装前准备
      • 2、安装流程
        • 2.1安装keil
        • 2.2破解keil5
        • 2.3安装STM32pack
      • 3、设置keil5
    • 三、简单STM32程序编写
      • 1、新建工程
      • 2、添加源文件
      • 3、设置仿真器模式
      • 4、编译调试
    • 四、分析HEX文件
    • 五、总结
    • 六、参考链接

一、环境配置

什么是MDK:Keil MDK是德国知名软件公司Keil开发的开发工具。开发者可以用MDK来编写、编译和生成基于STM32的可执行程序。本文章主要是学习如何安装、熟悉MDK并编写一个简单的STM32程序。

1、安装前准备

下载mdk5软件和stm32包的链接:

链接:https://pan.baidu.com/s/1b3YMHGOwa2Rsj3tFIuI58g
提取码:sey1

2、安装流程

2.1安装keil

下载压缩包到随便一个你自己创建的文件夹,然后解压至当前文件夹并打开解压后的文件夹:

在这里插入图片描述

安装keil软件:

(1)打开mdk_510.exe应用程序文件,点击next

在这里插入图片描述

(2)勾选I agree to…然后点击next

在这里插入图片描述

(3)选择安装路径,然后点击next

在这里插入图片描述

(4)输入名称和邮箱(随便写即可),点击next

在这里插入图片描述

(5)然后在弹出来的窗口里点击安装

在这里插入图片描述

(6)点击finish,确认图中的Show Release Notes勾上了

在这里插入图片描述

(8)上一步点击finish后会弹出来一个窗口,点击OK即可,然后软件会下载各种pack,鼠标会转圈然后下载失败。然后我们关闭窗口,接下来就开始手动安装stm32pack。

2.2破解keil5

破解后可以拥有十年的使用期

(1)在桌面打开刚刚安装好的keil5,点击file,再点击License Management

在这里插入图片描述

(2)复制里面CID

在这里插入图片描述

(3)再打开刚刚压缩包里面的keygen复制CID到里面显示CID的地方,target选择ARM,然后点击generate,复制生成的注册码

在这里插入图片描述

(4)然后打开keil5把生成的注册码再复制进第二步截图里面的new license code然后点击Add LIC,此时在上面的网格里就可以看到使用日期到了2032年,表明激活成功,在然后点击CLOSE关闭即可。

2.3安装STM32pack

(1)打开刚刚解压缩的文件夹,点击ARM.CMSIS3.20.4包

在这里插入图片描述

(2)然后一直点击next,最后点击finish即可

在这里插入图片描述

点击finish

在这里插入图片描述

(3)再回到刚刚解压缩后的文件里面,打开Keil.STM32F1xx_DFP.1.0.4pack
在这里插入图片描述

(4)然后点击next在这里插入图片描述

(5)然后安装完成后点击finish即可。到此安装就完成了。

3、设置keil5

这里设置一下keil5是因为避免输入中文的时候出现乱码

(1)首先打开keil5点击 Edit 找到最下面的configuration,点击进去

在这里插入图片描述

(2)在显示出来的页面里面确保Encoding的设置以及Tab size的设置如图所示:
在这里插入图片描述

三、简单STM32程序编写

接下来是编译一个简单的STM32程序

1、新建工程

(1)打开keil5,点击project,再点击new uVision project…创建工程

在这里插入图片描述

(2)然后就命名保存即可:
在这里插入图片描述

(3)然后可根据情况点击下图中的pack,这里我选的是STM32F103FRB包,然后点击OK保存。

在这里插入图片描述

(4)接下来对Manage Run-Time Environment进行设置,设置完成后点击OK,就可建立工程。

在这里插入图片描述

其实这两个文件刚开始都是存放在KEIL的安装目录下,当我们配置Manage Run-Time Environment选项框之后, 软件就会把选中好的文件从KEIL的安装目录复制到我们的工程目录:ProjectRTEDeviceARMCM3下面。 其中startup_ARMCM3.s是汇编编写的启动文件,system_ARMCM3.c是C语言编写的跟时钟相关的文件。 更加具体的可直接阅读这两个文件的源码。只要是Cortex-M3内核的单片机,这两个文件都适用。

到此这个项目的运行环境就建立完成了。

2、添加源文件

(1)点击OK后点击Target打开,再右键点击source group1,选择Add New Item to Group,

在这里插入图片描述

(2)然后选择Asm File (.s)文件,如下图所示,名字就看你自己怎么命名了,再点击add。

在这里插入图片描述

再把如下的程序粘贴进去:

 AREA MYDATA, DATAAREA MYCODE, CODEENTRYEXPORT __main__mainMOV R0, #10MOV R1, #11MOV R2, #12MOV R3, #13;LDR R0, =func01BL	func01;LDR R1, =func02BL	func02BL 	func03LDR LR, =func01LDR PC, =func03B .func01MOV R5, #05BX LRfunc02MOV R6, #06BX LRfunc03MOV R7, #07MOV R8, #08	BX LR

3、设置仿真器模式

(1)点击图中魔法棒,点击Target选项,检查芯片型号及晶振频率与所需是否相投同。

在这里插入图片描述

(2)再点击Debug打开下图界面,左边是进行软件仿真时的设置,右边是硬件调试时的设置。

在这里插入图片描述

设置软件仿真时的设置:

打开Debug选项选择操作类型,以及设置DialogDLL等参数,具体操作及作用如下:
(1)勾选Use Simulator设置使用软件仿真(图中没勾记得勾上)。
(2)勾选Run to main()使调试时,程序自动运行到main函数。
(3)Restore Debug Session Setting一般默认即可,该部分为复位调试窗口的组件,勾选后,调试时对应的窗口或状态恢复默认值。
(4)设置Dialog DLL为DARMSTM.DLL以及设置Parameter为-pSTM32F103ZE(芯片参数按使用的芯片相应修改即可,当然,部分芯片无法仿真),这部分为DLL文件及芯片参数设置区。

Dialog DLL和Parameter不修改的话,后面运行时可能会报错。

设置硬件调试的设置:

1.打开Debug选项选择操作调试器
2.设置Dialog DLL为TARMSTM.DLL以及设置Parameter为-pSTM32F103ZE,如上图所示。

4、编译调试

首先点击图中左边箭头处的符号,出现下边这样的提示则编译成功。

在这里插入图片描述

再点击途中右上角的放大镜就会出现下图的仿真界面
在这里插入图片描述

可以看见寄存器R5,R6,R7,R8的值和程序设置一样。

四、分析HEX文件

点击右上角魔法棒,再点击output勾选create hex file再推出点击调试就可以生成HEX文件了
在这里插入图片描述

然后再此目录下找到生成的HEX文件(图中的mk531是我自己的D盘下自己创建的目录,后面应该都是一样的):

在这里插入图片描述

打开HEX文件如下(可用记事本打开),开始分析:

记录build生成的 hex文件各段的大小,了解Hex文件格式及其前8个字节内容含义。

:020000040800F2
:100000000006002031010008390100083B0100080A
:100010003D0100083F010008410100080000000008
:100020000000000000000000000000004301000884
:1000300045010008000000004701000849010008D0
:100040004B0100084B0100084B0100084B01000860
:100050004B0100084B0100084B0100084B01000850
:100060004B0100084B0100084B0100084B01000840
:100070004B0100084B0100084B0100084B01000830
:100080004B0100084B0100084B0100084B01000820
:100090004B0100084B0100084B0100084B01000810
:1000A0004B0100084B0100084B0100084B01000800
:1000B0004B0100084B0100084B0100084B010008F0
:1000C0004B0100084B0100084B0100084B010008E0
:1000D0004B0100084B0100084B0100084B010008D0
:1000E0004B0100084B0100084B0100084B010008C0
:1000F0004B0100084B0100084B0100084B010008B0
:100100004B0100084B0100084B0100084B0100089F
:100110004B0100084B0100084B0100084B0100088F
:100120004B0100084B0100084B0100084B0100087F
:100130000948804709480047FEE7FEE7FEE7FEE77B
:10014000FEE7FEE7FEE7FEE7FEE7FEE704480549B7
:10015000054A064B7047000041020008990200085A
:100160000000002000060020000200200002002005
:10017000704770477047000080B500F001F880BDFF
:1001800082B041F204000021C4F20200019100910A
:1001900050F8041C41F4803140F8041C50F8041C51
:1001A00001F400310091019901310191009919B9CF
:1001B0000199B1F5A06FF1D150F8041C890354BF27
:1001C0000021012100910099012936D142F200015C
:1001D000C4F202010A6842F010020A600A6822F0C2
:1001E00003020A600A6842F002020A6001680160C4
:1001F00001680160016841F480610160016821F4D7
:100200007C110160016841F4E811016050F8041CA0
:1002100041F0807140F8041C50F8041C8901FBD5A2
:10022000016821F003010160016841F002010160F1
:10023000016801F00C010829FAD102B070470000F2
:1002400080B541F20000C4F202000168002241F0D2
:10025000010101604168CFF6FF0211404160016871
:100260004FF6FF72CFF6F66211400160016821F48B
:1002700080210160416821F4FE0141604FF41F01BB
:100280008160FFF779FF4EF60850CEF200004FF084
:100290000061016080BD00004FF00A004FF00B01CB
:1002A0004FF00C024FF00D0300F009F800F00AF8CF
:1002B00000F00BF8DFF81CE0DFF81CF0FEE74FF071
:1002C000050570474FF0060670474FF007074FF0DF
:0C02D00008087047BF020008CB020008BD
:040000050800029954
:00000001FF

分析:

该文件为16进制的一串字符。hex文件的第一排字符称之为扩展线性地址记录,也称为32位地址记录或HEX386记录。
在第一行数据020000040800F2中,其实际表达为0x02 0x00 0x00 0x04 0x08 0x00 0xf2。具体含义为:

  1. 第一个字节 0x02表示本行数据的长度;

  2. 第二、三字节 0x00 0x00表示本行数据的起始地址;

  3. 第四字节 0x04表示数据类型,数据类型有:0x00、0x01、0x02、0x03、0x04、0x05

    ‘00’ Data Rrecord:用来记录数据,HEX文件的大部分记录都是数据记录
    ‘01’ End of File Record: 用来标识文件结束,放在文件的最后,标识HEX文件的结尾

    ‘02’ Extended Segment Address Record: 用来标识扩展段地址的记录

    ‘03’ Start Segment Address Record:开始段地址记录

    ‘04’ Extended Linear Address Record: 用来标识扩展线性地址的记录
    ‘05’ Start Linear Address Record:开始线性地址记录

  4. 然后是数据,0x08 0x00

  5. 最后一个字节 0xf2为校验和。

五、总结

本文的目的是为了练习keil的安装与简单的STM32程序的编写,熟悉使用keil的方法、编写流程、参数调整方法以及对编译后生成的HEX文件进行简单分析。

六、参考链接

搭建并配置Keil嵌入式开发环境,完成一个基于STM32汇编程序的编写

HEX文件格式详解

[野火]uCOS-III内核实现与应用开发实战指南—基于STM32


http://chatgpt.dhexx.cn/article/4IK6M7vN.shtml

相关文章

分享嵌入式入门学习指导

最近有好多同学在咨询嵌入式该怎么入门,应该怎么学习,有什么好的学习方法推荐,以及嵌入式入门的学习路线。今天我就带着大家的问题,一一为大家解决。 首先嵌入式门槛虽然较高,但也跟其他事物一样,并不是牢不…

嵌入式系统开发入门

嵌入式系统开发 快捷键 alt / : 代码提示 ctrl 鼠标左: 查看代码实现 alt ← : 返回跳转前的代码项目1-Hello world 1、创建STM32项目 2、选择型号 3、配置项目名称 4、项目初始化概览 5、根据需求,查看文档引脚说明 …

嵌入式入门应该学什么?先从学习单片机开始!

可能很多人不知道嵌入式,不知道单片机。 但是我说最近几年的流行的应用大家就了解了。 1.无人机 2.共享单车 3.丰巢快递柜 4.充电桩 5.智能家居 这些产品内部都是通过嵌入式技术实现的,而大多数用的都是单片机。 那嵌入式和单片机的区别是什么&…

【嵌入式入门篇】嵌入式0基础沉浸式刷题篇1

嵌入式-入门沉浸式刷题篇 前言Q1:嵌入式牛牛宏大小Q2:嵌入式宏空间坐标数量Q3:嵌入式牛牛疑惑的变量Q4:嵌入式关键字constQ5:嵌入式机器的大小端Q6:嵌入式不用排序找数字Q7:嵌入式结构体对齐Q8&…

嵌入式入门应该先学习STM32还是先学习51

今天在粉丝群里一位嵌入式初学者问了一个这样的问题:学嵌入式应该先学什么?(文末有粉丝福利) 后面各位大佬也是对该问题发表了自己的观点,大多数人都认为应该先学51,因为51单片机直接对寄存器操作&#xf…

再说嵌入式入门

我之前写过几篇嵌入式入门的文章 不过我的读者还是觉得不够过瘾,我觉得还是要着重说一下嵌入式软件应该重点学习什么,guoqing收假最后一天写文。 精通C语言 精通C语言 精通C语言 C语言对于嵌入式软件来说就是他的命脉,不懂C语言的人根本就…

嵌入式开发入门基础篇

今天在逛CSDN的时候发现一篇嵌入式开发基础篇,看完感觉写的非常好,特拿过来跟大家分享一下。原篇地址:https://blog.csdn.net/qq_61672347/article/details/126760788。 文章目录 前言一、STM32的数据类型二、C语言中常用的关键字1、const关键…

嵌入式开发(一):嵌入式开发新手入门

系列文章: 嵌入式开发(一):嵌入式开发新手入门 嵌入式开发(二):开发板配置(自用) 嵌入式开发(三):海思Hi3559a交叉编译live555嵌入式…

嵌入式入门基础知识

文章目录 前言嵌入式基本知识ARM的理解ARM是一家公司一类芯片或产品的统称一项技术的名称,即采用RISC处理器体系架构ARM和intel的区分ARM和STM32的关系 处理器的基本概念MCUMPUDSPFPGA总结 ARM开发MCU开发和MPU开发的区别开源硬件 Arduino 和 Raspberry Pi总结 总结…

宽度学习系统BLS推广到在线学习的论文阅读记录

BELS: A BROAD ENSEMBLE LEARNING SYSTEM FOR DATA STREAM CLASSIFICATION 摘要:这篇文章主要是将BLS推广到适用于在线学习的邻域,提出了其如何进行适合在线学习的增量更新,以及面对概念漂移的适应 所提出的算法BELS 稀疏特征映射的更新 …

超越EfficientNet!MutualNet:一种自适应相互学习网络宽度和分辨率的网络

点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要15分钟 Follow小博主,每天更新前沿干货 【导读】今天给大家介绍一篇 ECCV 2020 Oral论文 ,该论文强调了同时考虑网络宽度和输入分辨率对有效网络设计的重要性。…

【AI不惑境】网络的宽度如何影响深度学习模型的性能?

大家好,这是专栏《AI不惑境》的第三篇文章,讲述模型宽度与模型性能的关系。 进入到不惑境界,就是向高手迈进的开始了,在这个境界需要自己独立思考。如果说学习是一个从模仿,到追随,到创造的过程&#xff0c…

CSS:宽高自适应详解

宽度自适应的应用 1.属性:width 2.属性值:px/% 3.宽度自适应的特点 - HTML,BODY表示浏览器,默认是块级元素,宽度是100% - 当块级元素不设置宽度或者设置100%的时候,宽度会沾满全屏(通栏效果) - 子级是块级元素,不设置宽度的时候会和父级等…

陈俊龙:从深度强化学习到宽度强化学习—结构,算法,机遇及挑战

来源:AI科技评论 摘要:如何赋予机器自主学习的能力,一直是人工智能领域的研究热点。 强化学习与宽度学习 如何赋予机器自主学习的能力,一直是人工智能领域的研究热点。在越来越多的复杂现实场景任务中,需要利用深度学习…

网络的宽度对深度学习模型的性能影响

目录 1 为什么需要足够的宽度 2,经典网络的第一层的宽度 3,宽度对模型性能的影响 4 如何更加有效地利用宽度 4.1 提高每一层通道的利用率 4.2 用其他通道的信息来补偿 5 经典网络模型宽度设计方法 5.1 采用多分支网络结构设计 1)ResN…

深度学习笔记(七):网络宽度(卷积核个数)的一些想法

文章目录 一、前言二、网络深度的意义三、宽度的意义四、 网络宽度设计4.1 网络宽度的下限在哪?4.2 网络宽度对模型性能的影响4.3 网络宽度和深度谁更加重要? 五、如何加有效地利用宽度?5.1 提高每一层通道的利用率5.2 用其他通道的信息来补偿…

宽度 深度学习 特点对比

宽度 & 深度学习 特点对比 推荐系统模型介绍实验过程与实验结果实验总结 为了提高神经网络的性能,是应该增加宽度呢?还是应该增加深度呢?增加宽度和增加深度各有什么样的效果呢? 本文对论文《Wide & Deep Learning for Re…

为什么是“深度”学习而不是宽度?

为什么是深度而不是宽度? 先说说我个人的理解,如下图所示,圆圈表示神经元,有两种方式。第一种,只有一层神经层,有8个神经元;第二种方式,有两层神经层,分别有2个和4个神经…

宽度学习系统:一种不需要深度结构的高效增量学习系统

宽度学习系统:一种不需要深度结构的高效增量学习系统 本文是对陈俊龙教授团队“Broad Learning System: An Effective and Efficient Incremental Learning System Without the Need for Deep Architecture”的中文综述,原文将在IEEE Transactions on Neu…

网络的宽度如何影响深度学习模型的性能?

大家好,这是专栏《AI不惑境》的第三篇文章,讲述模型宽度与模型性能的关系。 进入到不惑境界,就是向高手迈进的开始了,在这个境界需要自己独立思考。如果说学习是一个从模仿,到追随,到创造的过程&#xff0…