嵌入式学习札记(基于STM32L431) 一、ARM Cortex-M4微处理器

2023-10-11 22:10

本文主要是介绍嵌入式学习札记(基于STM32L431) 一、ARM Cortex-M4微处理器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ARM Cortex-M4微处理器

  • 写在前面
  • ARM Cortex-M4微处理器简介
    • ARM Cortex-M4微处理器内部结构概要
      • 位数
      • 总线结构
      • 中断控制
      • 存储器保护
      • 低功耗
      • 内部寄存器
    • 寻址方式与机器码获取方法
      • 指令保留字简表与寻址方式
        • 指令保留字简表
        • 寻址方式
          • 立即数寻址
          • 寄存器寻址
          • 直接寻址
          • 偏移寻址及寄存器间接寻址
      • 机器的指令码
        • 运行源文件
        • 执行程序所获得的信息
    • 基本指令分类解析
      • 数据传送类指令
        • 取数指令
        • 存数指令
        • 寄存器间数据传送指令
    • 汇编语言的基本语法
      • 汇编语言的格式
        • 标号
        • 操作码
        • 操作数
        • 注释
      • 常用伪指令简介
        • 系统预定义的段
        • 常量的定义
        • 程序中插入常量
        • 条件伪指令
        • 文件包含伪指令
        • 其他常用伪指令

写在前面

本系列学习主要参照了王宜怀老师主编,清华大学出版社出版的《嵌入式技术基础与实践(第六版)》一书,有兴趣的可以自行购买,正版书籍附赠开发版供实验所需

ARM Cortex-M4微处理器简介

ARM Cortex-M4微处理器内部结构概要

具体介绍请参考书籍

位数

Cortex-M4系列处理器为32位处理器,内部存储器,数据总线均为32位,采用Thumb-2技术,同时支持16位与32位指令

总线结构

采用哈佛架构(感兴趣可以自行查阅),统一的存储空间编址,32位寻址,最多支持4GB的存储空间;三级流水线设计;片上接口基于AMBA架构

中断控制

采用了集成嵌套向量中断控制器(NVIC),支持8~256个中断优先级,最多240个中断请求

存储器保护

可选的MPU

低功耗

多种低功耗特性和休眠模式

内部寄存器

M4微处理器的寄存器包含用于数据处理与控制的寄存器、特殊功能寄存器与浮点寄存器。特殊功能寄存器有预定义的功能,必须通过专用指令来访问。

寄存器类型序号
低位寄存器R0~R7
高位寄存器R8~R12
SPR13
LPR14
PCR15
PSR(程序状态寄存器)特殊功能寄存器
PRIMASK、FAULTMASK、BASEPRI(异常屏蔽寄存器)同上
CONTROL(控制寄存器)同上

寻址方式与机器码获取方法

CPU可以执行特定功能的操作命令被称为指令
CPU所能执行的各种指令的集合,成为该CPU的指令系统

指令保留字简表与寻址方式

指令保留字简表

其他指令请查阅《ARM v7-M 参考手册》

类型保留字含义
数据传送类ADR生成与PC指针相关的地址
LDR、LDRH、LDRB、LDRSB、LDRSH、LDMIA将存储器中的内容加载到寄存器中
STR、STRH、STRB、STMIA将寄存器中的内容存储到存储器中
MOV、MVN寄存器间数据传送
PUSH、POP进栈出栈
数据操作类下为子类
算数运算类ADC、ADD、SBC、SUB、MUL加、减、乘指令
CMN、CMP比较指令
逻辑运算类AND、ORR、EOR、BIC按位与、或、异或、位段清零
数据序转类REV、REVSH、REVH反转字节序
扩展类SXTB、SXTH、UXTB、UXTH无符号扩展字节、有符号扩展字节
………………
寻址方式
立即数寻址

操作数直接通过指令给出。用“#”作为立即数的前导标识符。M4微处理器的立即数范围是0x00~-0xFF。例如:

	MOV 	R0, # 0xFF 		//立即数0xFF装入R0寄存器SUB		R1, R0, # 1		//R1←R0 - 1
寄存器寻址

操作数来自寄存器。例如:

	MOV 	R0, R1				//将R1寄存器内容装入R0寄存器
直接寻址

操作数来自存储单元,指令中直接给出存储单元地址。指令码中显示给出数据的位数,如:字、半字、单字节。例如:

	LDR 	Rt, label				//从标号label处连续读取4字节到寄存器中LDRH 	Rt, label				//从地址label处读取半字到Rt中LDRB 	Rt, label				//从地址label处读取字节到Rt中
偏移寻址及寄存器间接寻址

偏移寻址的操作数来自存储单元,指令中通过寄存器及偏移量给出存储单元的地址。偏移量不超过4KB。偏移量为0的偏移寻址也成为寄存器间接寻址。例如:

	LDR 	R3, [PC, # 100]			//从地址(PC+100)处读取4字节到R3中LDR 	R3, [R4]				//以R4中内容为地址,读取4字节到R3中

机器的指令码

运行源文件

利用开发环境打开工程…\CH02-1。测试代码如下:

Label:MOV	R0, # 0xDELDR		R0, = data_format1LDR		R1, = LabelLDR 	R2, [R1]BL		printf

执行结果如下图:
在这里插入图片描述

执行程序所获得的信息

从上图现实的内容可以看出,标号代表的地址为0900D87E,这就是指令MOV R0,# 0xDE机器码要存放的开放地址,各地址存储内容如下表:

地址0800D87E0800D87F0800D8800800D881
内容4FF0DE00

STM32数据存储采用的是小段模式,即将2个字节以上的一个数据的低字节放在存储器低地址单元,高字节放在高地址单元。

基本指令分类解析

数据传送类指令

有两种情况:一是取存储器地址空间中的数传送到寄存器中,二是将寄存器中的数传送到另一寄存器或存储器地址空间中

取数指令
编号指令说明
(1)LDR Rt, [< Rn | SP > {, #imm }]从地址{ SP/Rn + # imm}处,取字到Rt中,imm = 0, 4, 8, …, 1020
LDR Rt, [Rn, Rm]从地址Rn + Rm处读取字到Rt中
LDR Rt, label从标号label指定的存储器单元取数到寄存器,标号label必须在当前指令的-4~4KB范围内,且应4字节对齐
(2)LDRH Rt, [Rn {, #imm}]从地址{Rn + #imm}处,取半字到Rt中,imm = 0, 2, 4, …, 62
LDRH Rt, [Rn, Rm]从地址Rn + Rm处读取半字到Rt中
(3)LDRB Rt, [Rn {, #imm}]从地址{Rn + #imm}处,取半字到Rt中,imm = 0~31
LDRB Rt, [Rn, Rm]从地址Rn + Rm处读取字节到Rt中
(4)LDRSH Rt, [Rn, Rm]从地址Rn + Rm处读取半字到Rt中,并带符号扩展至32位
(5)LDRSB Rt, [Rn, Rm]从地址Rn + Rm处读取字节到Rt中,并带符号扩展至32位
(6)LDM Rt{ ! }, reglist从地址Rn处读取多个字, 加载到reglist列表寄存器中,每读一个字后Rn自增一次
存数指令

Rt,Rn,Rm必须为R0~R7中的一个

编号指令说明
(7)STR Rt, [< Rn | SP > {, #imm }]把Rt中的字存储到地址SP/Rn + #imm处,imm = 0, 4, 8,…, 1020
STR Rt, [Rn, Rm]把Rt中的字存储到地址Rn + Rm处
(8)STRH Rt, [Rn {, #imm}]把Rt中的低半字存储到地址SP/Rn + #imm处,imm = 0, 2, 4, …, 62
STRH Rt, [Rn, Rm]把Rt中的低半字存储到地址Rn + Rm处
(9)STRB Rt, [Rn {, #imm}]把Rt中的低字节存储到地址SP/Rn + #imm处,imm = 0~31
STRB Rt, [Rn, Rm]把Rt中的低字节存储到地址Rn + Rm处
(10)STM Rn!, reglist存储多个字到Rn处,每存一个字后Rn自增一次
寄存器间数据传送指令
编号指令说明
(11)MOV Rd, RmRd←Rm,Rd只可以是R0~R7
(12)MOVS Rd, # imm功能同MOV, 且影响N、Z标志
(13)MVN Rd, Rm将寄存器Rm中的数据取反,传送给寄存器Rd,影响N、Z标志

其他指令请参考书籍,在此不再罗列

汇编语言的基本语法

汇编语言源程序以行为单位进行设计,每行最多可以包含一下4部分

标号:操作码操作数注释

汇编语言的格式

标号
  1. 如果一个语句有标号,则标号必须书写在汇编语句的开头部分
  2. 可以组成标号的字符有字母A ~ Z、 a ~ z、数字0 ~ 9、下划线(_),美元符号($),但开头的第一个符号不能为数字和 $
  3. 编译器对标号中字母的大小写敏感,但指令不区分大小
  4. 标号长度基本不受限制,但实际使用时通常不超过20个字符。
  5. 标号后必须带冒号(:)
  6. 一个标号在一个文件(程序)中只能被定义一次,否则出现重复定义,不能通过编译
  7. 一行语句只能有一个标号,编译器将把当前程序计数器的值赋给该标号
操作码

操作码包括指令码和伪指令。
对于有标号的行,必须至少用一个空格或制表符将标号与操作码隔开;对于没有标号的行,不能从第一列开始写指令码,应以空格或制表符开头。

操作数

操作数可以使地址,标号或指令码定义的常数,也可以是有伪运算符构成的表达式。
如果一条指令或伪指令有操作数,则操作数与操作码之间必须用空格隔开书写。操作数多于一个的,操作数之间用逗号分隔。操作数也可以是M4内部寄存器,或者另一条指令的特定参数。
操作数一般都有一个存放结果的寄存器,这个寄存器在操作数的最前面

1、常数标识
编译器识别的常数有十进制、十六进制(0x)、二进制(0b)
2、“#”表示立即数
一个常数前添加“#”表示一个立即数;不加“#”时,表示一个地址。
3、圆点
如果圆点(.)单独出现在语句操作码之后的操作数位置上,则代表当前程序计数器的值被放置在圆点的位置。
4、伪运算符
略。详情请查阅资料

注释

类似于C语言

常用伪指令简介

在CCS开发环境下,所有的汇编命令都是以“.”开头的

系统预定义的段

C语言程序在经过gcc编译器最终生成.elf格式的可执行程序。.elf可执行程序是以段为单位来组织文件的。通常划分为如下三个段:

	.text				@只读的代码区.data				@可读可写的数据区.bss				@是可读可写且没有初始化的数据区
常量的定义

常量的定义可以使用.equ汇编指令,例如:

	.equ	_NVIC_ICER,	0xE00E180...LDR		R0, = _NVIC_ICER				@将0xE00E180放到R0中

常量的定义还可以使用.set汇编指令,例如:

	.set 	_NVIC_ICER,	0xE00E180
程序中插入常量
插入数据的类型伪指令
.word
半字.hword
字节.byte
字符串.ascii.asciz
		LDR R3, = NUMBERLDR R4, [R3]...LDR R0, = HELLO_TEXTBL	PrintText...ALIGN 4NUMBER:.word	0x123456789HELLO_TEXT:.asciz 	"hello\n"
条件伪指令

.if条件伪指令后面紧跟一个恒定的表达式,并且最后要以.endif结尾。中间如果有其他条件,可以用.else编写汇编语句。
.ifdef标号表示如果标号被定义,则执行下面的代码。

文件包含伪指令
	.include "filename"
其他常用伪指令

(1).section:用户可以通过该指令来自定义一个段

	.section .isr_vector, "a"		@定义一个.isr_vector段,"a"表示允许段

(2).global:用来定义一个全局符号

	.global	symbol

(3).extern:.extern symbol 声明symbol为外部函数,调用时可以遍历所有文件找到该函数并使用

	.global	mainbl		main

(4).align:通过填充字节使当前位置满足一定的对齐方式
(5).end:声明汇编文件的结束
其余详见《GNU汇编语法》

这篇关于嵌入式学习札记(基于STM32L431) 一、ARM Cortex-M4微处理器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/191168

相关文章

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

《offer来了》第二章学习笔记

1.集合 Java四种集合:List、Queue、Set和Map 1.1.List:可重复 有序的Collection ArrayList: 基于数组实现,增删慢,查询快,线程不安全 Vector: 基于数组实现,增删慢,查询快,线程安全 LinkedList: 基于双向链实现,增删快,查询慢,线程不安全 1.2.Queue:队列 ArrayBlockingQueue:

硬件基础知识——自学习梳理

计算机存储分为闪存和永久性存储。 硬盘(永久存储)主要分为机械磁盘和固态硬盘。 机械磁盘主要靠磁颗粒的正负极方向来存储0或1,且机械磁盘没有使用寿命。 固态硬盘就有使用寿命了,大概支持30w次的读写操作。 闪存使用的是电容进行存储,断电数据就没了。 器件之间传输bit数据在总线上是一个一个传输的,因为通过电压传输(电流不稳定),但是电压属于电势能,所以可以叠加互相干扰,这也就是硬盘,U盘

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa