嵌入式系统 - 快速指南
嵌入式系统 - 概述
系统
系统是一种安排,其中所有单元按照一组规则组装在一起工作。它也可以被定义为一种根据固定计划工作、组织或完成一项或多项任务的方式。例如,手表是一种时间显示系统。它的组件遵循一组规则来显示时间。如果其中一个部件出现故障,手表就会停止工作。所以我们可以说,在一个系统中,它的所有子组件都是相互依赖的。
嵌入式系统
顾名思义,嵌入式意味着某种东西附加到另一个东西上。嵌入式系统可以被认为是嵌入了软件的计算机硬件系统。嵌入式系统可以是一个独立的系统,也可以是一个大系统的一部分。嵌入式系统是基于微控制器或微处理器的系统,旨在执行特定任务。例如,火灾报警器是一个嵌入式系统;它只会感觉到烟雾。
嵌入式系统具有三个组件 -
它有硬件。
它有应用软件。
它具有实时操作系统(RTOS),用于监督应用程序软件并提供机制,让处理器通过遵循控制延迟的计划来按照调度运行进程。RTOS 定义了系统的工作方式。它设定应用程序执行期间的规则。小型嵌入式系统可能没有 RTOS。
因此,我们可以将嵌入式系统定义为基于微控制器的、软件驱动的、可靠的实时控制系统。
嵌入式系统的特点
单功能- 嵌入式系统通常执行专门的操作并重复执行相同的操作。例如:寻呼机始终充当寻呼机。
严格约束- 所有计算系统都对设计指标有限制,但嵌入式系统上的设计指标可能特别严格。设计指标是对实现功能(例如成本、尺寸、功耗和性能)的衡量。它的尺寸必须适合单个芯片,必须足够快地执行数据以实时处理数据,并且消耗最小的功耗以延长电池寿命。
反应性和实时性- 许多嵌入式系统必须不断地对系统环境的变化做出反应,并且必须实时计算某些结果,没有任何延迟。考虑一个汽车巡航控制器的例子;它持续监控速度和制动传感器并对其做出反应。它必须在有限的时间内重复计算加速度或减加速度;延迟计算可能会导致无法控制汽车。
基于微处理器- 它必须是基于微处理器或微控制器。
内存- 它必须有一个内存,因为它的软件通常嵌入在 ROM 中。它不需要计算机中的任何辅助存储器。
连接- 它必须连接外围设备才能连接输入和输出设备。
硬件-软件系统- 软件用于提供更多功能和灵活性。硬件用于性能和安全性。
优点
- 轻松定制
- 低功耗
- 低成本
- 增强性能
缺点
- 高开发投入
- 更长的上市时间
嵌入式系统的基本结构
下图显示了嵌入式系统的基本结构 -
传感器- 它测量物理量并将其转换为可由观察者或任何电子仪器(如 A2D 转换器)读取的电信号。传感器将测量的数量存储到存储器中。
AD转换器- 模数转换器将传感器发送的模拟信号转换为数字信号。
处理器和 ASIC - 处理器处理数据以测量输出并将其存储到内存中。
DA 转换器- 数模转换器将处理器馈送的数字数据转换为模拟数据
执行器- 执行器将 DA 转换器给出的输出与存储在其中的实际(预期)输出进行比较,并存储批准的输出。
嵌入式系统 - 处理器
处理器是嵌入式系统的核心。它是接受输入并在处理数据后产生输出的基本单元。对于嵌入式系统设计人员来说,必须具备微处理器和微控制器的知识。
系统中的处理器
处理器有两个基本单元 -
- 程序流程控制单元 (CU)
- 执行单位(欧盟)
CU包括用于从存储器获取指令的获取单元。EU 具有实现与数据传输操作和从一种形式到另一种形式的数据转换相关的指令的电路。
EU 包括算术逻辑单元 (ALU) 以及执行程序控制任务指令的电路,例如中断或跳转到另一组指令。
处理器运行取指周期并以与从内存中取指相同的顺序执行指令。
处理器类型
处理器可以属于以下类别 -
通用处理器 (GPP)
- 微处理器
- 微控制器
- 嵌入式处理器
- 数字信号处理器
- 媒体处理器
专用系统处理器 (ASSP)
应用特定指令处理器 (ASIP)
专用集成电路 (ASIC) 或超大规模集成 (VLSI) 电路上的 GPP 内核或 ASIP 内核。
微处理器
微处理器是具有 CPU 的单个 VLSI 芯片。此外,它还可能具有其他单元,例如教练、浮点处理算术单元和流水线单元,有助于更快地处理指令。
早期微处理器的读取和执行周期由大约 1 MHz 的时钟频率引导。处理器现在的运行时钟频率为 2GHz
微控制器
微控制器是一种单芯片VLSI单元(也称为微型计算机),虽然计算能力有限,但具有增强的输入/输出能力和许多片上功能单元。
中央处理器 | 内存 | 只读存储器 |
输入/输出端口 | 定时器 | 串行COM端口 |
微控制器特别用于嵌入式系统,用于具有片上程序存储器和设备的实时控制应用。
微处理器与微控制器
现在让我们看一下微处理器和微控制器之间最显着的区别。
微处理器 | 微控制器 |
---|---|
微处理器本质上是多任务处理的。可以一次执行多个任务。例如,在计算机上我们可以一边播放音乐,一边在文本编辑器中编写文本。 | 单一任务导向。例如,洗衣机仅设计用于洗涤衣服。 |
RAM、ROM、I/O 端口和定时器可以从外部添加,并且数量可以有所不同。 | RAM、ROM、I/O 端口和定时器不能从外部添加。这些组件将一起嵌入在芯片上,并且数量固定。 |
设计人员可以决定所需的内存或 I/O 端口数量。 | 固定数量的内存或 I/O 使微控制器非常适合有限但特定的任务。 |
外部存储器和 I/O 端口的外部支持使得基于微处理器的系统变得更重、更昂贵。 | 微控制器比微处理器轻且便宜。 |
外部设备需要更大的空间,并且功耗更高。 | 基于微控制器的系统消耗更少的功率并且占用更少的空间。 |
嵌入式系统 - 架构类型
8051 微控制器使用 8 位数据总线工作。因此它们最多可以支持64K的外部数据存储器和64K的外部程序存储器。总的来说,8051 微控制器可以寻址 128k 的外部存储器。
当数据和代码位于不同的内存块时,该体系结构称为哈佛体系结构。如果数据和代码位于同一内存块中,则该体系结构称为冯·诺依曼体系结构。
冯·诺依曼架构
冯·诺依曼架构首先由计算机科学家约翰·冯·诺依曼提出。在此架构中,指令和数据都存在一条数据路径或总线。因此,CPU 一次执行一项操作。它要么从内存中获取指令,要么对数据执行读/写操作。因此指令读取和数据操作不能同时发生,共享公共总线。
冯·诺依曼架构支持简单的硬件。它允许使用单个顺序存储器。今天的处理速度远远超过了内存访问时间,我们在处理器本地使用了非常快但少量的内存(缓存)。
哈佛建筑
哈佛架构为指令和数据提供单独的存储和信号总线。该架构的数据存储完全包含在 CPU 内,并且无法将指令存储作为数据进行访问。计算机使用内部数据总线为程序指令和数据提供单独的存储区域,从而允许同时访问指令和数据。
需要操作员加载程序;处理器无法自行启动。在哈佛架构中,不需要使两个存储器共享属性。
冯·诺依曼架构与哈佛架构
冯·诺依曼架构与哈佛架构的区别如下。
冯诺依曼架构 | 哈佛建筑 |
---|---|
代码和数据共享单个内存。 | 代码和数据的独立存储器。 |
处理器需要在单独的时钟周期中获取代码,并在另一个时钟周期中获取数据。所以需要两个时钟周期。 | 单个时钟周期就足够了,因为使用单独的总线来访问代码和数据。 |
速度更快,因此耗时更少。 | 速度较慢,因此更耗时。 |
设计简单。 | 设计复杂。 |
CISC 和 RISC
CISC 是复杂指令集计算机。它是一台可以处理大量指令的计算机。
在 20 世纪 80 年代初期,计算机设计者建议计算机应使用更少的指令和简单的结构,以便它们可以在 CPU 中更快地执行,而无需使用内存。此类计算机被分类为精简指令集计算机或 RISC。
CISC 与 RISC
CISC 与 RISC 的区别如下:
CISC | 精简指令集计算机 |
---|---|
更大的指令集。易于编程 | 较小的一组指令。编程困难。 |
编译器设计更简单,考虑更大的指令集。 | 编译器设计复杂。 |
多种寻址方式导致指令格式复杂。 | 寻址方式少,指令格式固定。 |
指令长度是可变的。 | 指令长度各不相同。 |
每秒更高的时钟周期。 | 每秒低时钟周期。 |
重点是硬件。 | 重点是软件。 |
控制单元使用微程序单元实现大型指令集。 | 每条指令都由硬件执行。 |
执行速度较慢,因为指令要从内存中读取并由解码器单元解码。 | 执行速度更快,因为每条指令都由硬件执行。 |
管道化是不可能的。 | 考虑到单个时钟周期,指令的流水线是可能的。 |
嵌入式系统 - 工具和外围设备
编译器和汇编器
编译器
编译器是一种计算机程序(或一组程序),它将用一种编程语言(源语言)编写的源代码转换为另一种计算机语言(通常是二进制格式)。转换的最常见原因是创建可执行程序。“编译器”这个名称主要用于将源代码从高级编程语言翻译为低级语言(例如汇编语言或机器代码)的程序。
交叉编译器
如果编译后的程序可以在具有与编译器编译该程序的计算机不同的CPU或操作系统的计算机上运行,则该编译器被称为交叉编译器。
反编译器
能够将程序从低级语言翻译成高级语言的程序称为反编译器。
语言转换器
翻译用不同高级语言编写的程序的程序通常称为语言翻译器、源到源翻译器或语言转换器。
编译器可能会执行以下操作 -
- 预处理
- 解析
- 语义分析(语法指导翻译)
- 代码生成
- 代码优化
装配工
汇编程序是一种程序,它采用基本的计算机指令(称为汇编语言)并将其转换为计算机处理器可以用来执行其基本操作的位模式。汇编器通过将汇编指令助记符转换为操作码,将符号名称解析为内存位置来创建目标代码。汇编语言使用助记符来表示每个低级机器操作(操作码)。
嵌入式系统中的调试工具
调试是一个有条不紊的过程,旨在发现并减少计算机程序或电子硬件中的错误数量,使其按预期工作。当子系统紧密耦合时,调试会很困难,因为一个子系统中的微小更改可能会在另一个子系统中产生错误。嵌入式系统中使用的调试工具在开发时间和调试功能方面差异很大。我们将在这里讨论以下调试工具 -
- 模拟器
- 微控制器入门套件
- 模拟器
模拟器
通过在用于代码开发的主机上进行模拟来测试 MCU/系统的代码。模拟器尝试用软件对整个微控制器的Behave进行建模。
模拟器的功能
模拟器执行以下功能 -
定义处理器或处理设备系列及其针对目标系统的各种版本。
随着每个步骤的执行,使用标签和符号参数监视源代码部分的详细信息。
为每个单步执行提供目标系统的 RAM 和模拟端口的状态。
监视系统响应并确定吞吐量。
提供程序计数器内容与处理器寄存器的输出的跟踪。
提供当前命令的详细含义。
监视从键盘输入或从菜单中选择的模拟器命令的详细信息。
支持条件(最多8个或16个或32个条件)和无条件断点。
提供断点和跟踪,是重要的测试和调试工具。
有助于同步内部外设和延迟。
微控制器入门套件
微控制器入门套件包括 -
- 硬件板(评估板)
- 系统内编程器
- 一些软件工具,如编译器、汇编器、链接器等。
- 有时,IDE 和代码大小会限制编译器的评估版本。
与模拟器相比,这些套件的一大优势是它们可以实时工作,因此可以轻松进行输入/输出功能验证。然而,入门套件对于开发简单的微控制器项目来说是完全足够的,也是最便宜的选择。
模拟器
模拟器是一个硬件套件或软件程序,或者可以两者兼有,它在另一个计算机系统(主机)中模拟一个计算机系统(客户)的功能,与第一个计算机系统不同,因此模拟的Behave与实际Behave非常相似真实系统(来宾)的。
仿真是指电子设备中的计算机程序仿真(模仿)另一个程序或设备的能力。仿真侧重于重新创建原始计算机环境。模拟器能够与数字对象的真实性保持更紧密的联系。模拟器可以帮助用户在平台上的任何类型的应用程序或操作系统上工作,就像软件在其原始环境中运行一样。
嵌入式系统中的外围设备
嵌入式系统通过其外设与外界进行通信,例如以下&mins;
- 串行通信接口 (SCI),如 RS-232、RS-422、RS-485 等。
- 同步串行通信接口,如 I2C、SPI、SSC 和 ESSI
- 通用串行总线 (USB)
- 多媒体卡(SD 卡、CF 卡等)
- 以太网、LonWorks 等网络
- 现场总线,如 CAN 总线、LIN 总线、PROFIBUS 等。
- 定时器,如 PLL、捕获/比较和时间处理单元。
- 离散 IO 又名通用输入/输出 (GPIO)
- 模拟转数字/数字转模拟 (ADC/DAC)
- JTAG、ISP、ICSP、BDM 端口、BITP 和 DP9 端口等调试
选择微控制器的标准
选择微控制器时,请确保它能够满足手头的任务并且具有成本效益。我们必须了解 8 位、16 位或 32 位微控制器是否能够最好地处理任务的计算需求。此外,选择微控制器时应牢记以下几点 -
速度- 微控制器可以支持的最高速度是多少?
封装- 是 40 引脚 DIP(双列直插式封装)还是 QFP(四方扁平封装)?这对于最终产品的空间、组装和原型设计非常重要。
功耗- 这是电池供电产品的一个重要标准。
芯片上RAM 和 ROM 的数量。
芯片上I/O 引脚和定时器的数量。
每单位成本- 这对于使用微控制器的产品的最终成本而言非常重要。
此外,请确保您拥有微控制器可用的编译器、调试器和汇编器等工具。最重要的是,您应该从可靠的来源购买微控制器。
嵌入式系统 - 8051 微控制器
8051简史
第一个微处理器4004是由 Intel 公司发明的。8085和8086微处理器也是英特尔发明的。1981 年,Intel 推出了名为8051的 8 位微控制器。它被称为片上系统,因为它有 128 字节 RAM、4K 字节片上 ROM、两个定时器、一个串行端口和 4 个端口(8 位宽),所有这些都在一个芯片上。当它广泛流行时,英特尔允许其他制造商制造和销售不同风格的 8051,其代码与 8051 兼容。这意味着,如果您为一种风格的 8051 编写程序,它也可以在其他风格上运行,无论哪种风格。制造商。这导致了具有不同速度和片上 RAM 数量的多个版本。
8051 口味/成员
8052 微控制器- 8052 具有 8051 微控制器的所有标准功能以及额外的 128 字节 RAM 和一个额外的定时器。它还具有 8K 字节的片上程序 ROM,而不是 4K 字节。
8031 微控制器- 它是 8051 系列的另一个成员。该芯片通常被称为无 ROM 8051,因为它具有 0K 字节的片上 ROM。您必须向其添加外部 ROM 才能使用它,其中包含要获取和执行的程序。该程序最大可达 64K 字节。但在向 8031 添加外部 ROM 的过程中,它丢失了 4 个端口中的 2 个端口。为了解决这个问题,我们可以在8031上添加一个外部I/O
8051家族成员对比
下表比较了 8051、8052 和 8031 中的可用功能。
特征 | 8051 | 8052 | 8031 |
---|---|---|---|
ROM(字节) | 4K | 8K | 0K |
内存(字节) | 128 | 256 | 128 |
定时器 | 2 | 3 | 2 |
输入/输出引脚 | 32 | 32 | 32 |
串行端口 | 1 | 1 | 1 |
中断源 | 6 | 8 | 6 |
8051微控制器的特点
8051 微控制器具有以下功能 -
- 4KB 字节片上程序存储器 (ROM)
- 128 字节片上数据存储器 (RAM)
- 四个寄存器库
- 128 个用户定义的软件标志
- 8位双向数据总线
- 16位单向地址总线
- 32 个通用寄存器,每个寄存器 8 位
- 16位定时器(通常是2个,但可能有更多或更少)
- 三个内部中断和两个外部中断
- 四个8位端口,(短型号有两个8位端口)
- 16位程序计数器和数据指针
- 8051 还可能具有许多特殊功能,例如 UART、ADC、运算放大器等。
8051 微控制器框图
下图显示了 8051 微控制器的框图 -
嵌入式系统 - I/O 编程
在 8051 中,I/O 操作是使用 4 个端口和 40 个引脚完成的。下面的引脚图显示了 40 个引脚的详细信息。I/O操作端口预留32个引脚,每个端口8个引脚。其他 8 个引脚指定为 V cc、GND、XTAL1、XTAL2、RST、EA(条)、ALE/PROG(条)和 PSEN(条)。
它是 40 引脚 PDIP(塑料双列直插式封装)
注- 在 DIP 封装中,您可以通过 IC 中间的切口识别第一个引脚和最后一个引脚。第一个引脚位于此切割标记的左侧,最后一个引脚(即本例中的第 40个引脚)位于切割标记的右侧。
I/O 端口及其功能
四个端口 P0、P1、P2 和 P3,每个端口使用 8 个引脚,因此它们是 8 位端口。复位后,所有端口均配置为输入,准备用作输入端口。当第一个 0 写入端口时,它成为输出。要将其重新配置为输入,必须将 1 发送到端口。
端口 0(引脚 32 – 引脚 39)
它有 8 个引脚(32 至 39)。它可用于输入或输出。与 P1、P2、P3 端口不同,我们通常将 P0 连接到 10K 欧姆的上拉电阻,将其用作开漏输入或输出端口。
它也被指定为 AD0-AD7,允许它用作地址和数据。对于8031(即ROMless芯片),当我们需要访问外部ROM时,P0将用于地址总线和数据总线。ALE(引脚号 31)指示 P0 是否有地址或数据。当ALE=0时,它提供数据D0-D7,但当ALE=1时,它提供地址A0-A7。如果没有可用的外部存储器连接,P0 必须在外部连接 10K 欧姆的上拉电阻。
MOV A,#0FFH ;(comments: A=FFH(Hexadecimal i.e. A=1111 1111) MOV P0,A ;(Port0 have 1's on every pin so that it works as Input)
端口 1(引脚 1 至 8)
它是一个 8 位端口(引脚 1 至 8),可用作输入或输出。它不需要上拉电阻,因为它们已经在内部连接。复位后,端口 1 被配置为输入端口。以下代码可用于将 55H 和 AAH 的交替值发送到端口 1。
;Toggle all bits of continuously MOV A,#55 BACK: MOV P2,A ACALL DELAY CPL A ;complement(invert) reg. A SJMP BACK
如果端口 1 配置为用作输出端口,则要再次将其用作输入端口,请通过向其所有位写入 1 对其进行编程,如以下代码所示。
;Toggle all bits of continuously MOV A ,#0FFH ;A = FF hex MOV P1,A ;Make P1 an input port MOV A,P1 ;get data from P1 MOV R7,A ;save it in Reg R7 ACALL DELAY ;wait MOV A,P1 ;get another data from P1 MOV R6,A ;save it in R6 ACALL DELAY ;wait MOV A,P1 ;get another data from P1 MOV R5,A ;save it in R5
端口 2(引脚 21 至 28)
端口 2 总共占用 8 个引脚(引脚 21 至 28),可用于输入和输出操作。正如 P1(端口 1)一样,P2 也不需要外部上拉电阻,因为它们已经在内部连接。它必须与 P0 一起使用,为外部存储器提供 16 位地址。因此也指定为(A0-A7),如引脚图所示。当8051连接到外部存储器时,它为16位地址的高8位提供路径,并且不能用作I/O。复位后,端口 2 被配置为输入端口。以下代码可用于将 55H 和 AAH 的交替值发送到端口 2。
;Toggle all bits of continuously MOV A,#55 BACK: MOV P2,A ACALL DELAY CPL A ; complement(invert) reg. A SJMP BACK
如果端口 2 配置为用作输出端口,则要再次将其用作输入端口,请通过向其所有位写入 1 来对其进行编程,如以下代码所示。
;Get a byte from P2 and send it to P1 MOV A,#0FFH ;A = FF hex MOV P2,A ;make P2 an input port BACK: MOV A,P2 ;get data from P2 MOV P1,A ;send it to Port 1 SJMP BACK ;keep doing that
端口 3(引脚 10 至 17)
它也是8位的,可以用作输入/输出。该端口提供一些极其重要的信号。P3.0 和 P3.1 分别是 RxD(接收器)和 TxD(发送器),共同用于串行通信。P3.2 和P3.3 引脚用于外部中断。P3.4和P3.5分别用于定时器T0和T1。P3.6 和 P3.7 是写入 (WR) 和读取 (RD) 引脚。这些是低电平有效引脚,意味着当赋予它们 0 时它们将被激活,并且这些引脚用于向基于 8031 的系统中的外部 ROM 提供读写操作。
P3位 | 功能 | 别针 |
---|---|---|
P3.0 | 接收数据 | 10 |
P3.1 < | 发送端 | 11 |
P3.2 < | INT0 的补码 | 12 |
P3.3 < | INT1 | 13 |
P3.4 < | T0 | 14 |
P3.5 < | T1 | 15 |
P3.6 < | WR | 16 |
P3.7 < | RD 的补充 | 17 号 |
端口 0 和端口 2 的双重角色
端口 0 的双重角色- 端口 0 也被指定为 AD0–AD7,因为它可用于数据和地址处理。将 8051 连接到外部存储器时,端口 0 可以提供地址和数据。然后,8051 微控制器将输入复用为地址或数据,以节省引脚。
端口 2 的双重作用- 除了用作 I/O 外,端口 P2 还与端口 0 一起为外部存储器提供 16 位地址总线。端口 P2 也指定为 (A8–A15),而端口 0 提供通过 A0–A7 降低 8 位。换句话说,我们可以说,当 8051 连接到最大可达 64KB 的外部存储器 (ROM) 时,这可以通过 16 位地址总线实现,因为我们知道 216 = 64KB。Port2 用于 16 位地址的高 8 位,不能用于 I/O,这是外部 ROM 的任何程序代码的寻址方式。
引脚硬件连接
V cc - 引脚 40 为芯片提供电源,电压为 +5 V。
Gnd - 引脚 20 为参考提供接地。
XTAL1、XTAL2(引脚 18 和引脚 19) - 8051 有片上振荡器,但需要外部时钟来运行。石英晶体连接在芯片的 XTAL1 和 XTAL2 引脚之间。该晶体还需要两个 30pF 的电容器来生成所需频率的信号。每个电容器的一侧接地。8051 IC 有多种速度可供选择,这完全取决于石英晶体,例如 20 MHz 微控制器需要频率不超过 20 MHz 的晶体。
RST(引脚 9) - 它是输入引脚和高电平有效引脚。在该引脚上施加高脉冲(即 1)后,微控制器将重置并终止所有活动。此过程称为上电复位。激活上电复位将导致寄存器中的所有值丢失。它将把程序计数器设置为全 0。为了确保复位的有效输入,高脉冲必须至少保持两个机器周期的高电平,然后才能变低,这取决于电容器值及其充电速率。(机器周期是执行单个指令所需的最小频率)。
EA 或外部访问(引脚 31) - 它是一个输入引脚。该引脚为低电平有效引脚;一旦施加低脉冲,它就会被激活。如果微控制器 (8051/52) 具有片上 ROM,则 EA(条形)引脚连接至 V cc。但在没有片上 ROM 的 8031 微控制器中,代码存储在外部 ROM 中,然后由微控制器读取。在这种情况下,我们必须将EA(引脚号31)连接到Gnd,以表明程序代码存储在外部。
PSEN 或程序存储启用(引脚 29) - 这也是一个低电平有效引脚,即在施加低脉冲后被激活。它是一个输出引脚,与基于 8031(即 ROMLESS)系统中的 EA 引脚一起使用,以允许在外部 ROM 中存储程序代码。
ALE 或(地址锁存使能) - 这是一个输出引脚,高电平有效。特别用于8031 IC与外部存储器的连接。可以在决定 P0 引脚用作地址总线还是数据总线时使用。当 ALE = 1 时,P0 引脚用作数据总线;当 ALE = 0 时,P0 引脚用作地址总线。
I/O 端口和位寻址能力
这是在为 8051 编写代码时使用最广泛的 8051 功能。有时我们只需要访问端口的 1 或 2 位,而不是整个 8 位。8051 提供访问端口各个位的能力。
以单位方式访问端口时,我们使用语法“SETB X.Y”,其中 X 是端口号(0 到 3),Y 是数据位 D0-D7 的位数(0 到 7)其中 D0 是 LSB,D7 是 MSB。例如,“SETB P1.5”设置端口 1 的高位 5。
以下代码显示了如何连续切换位 P1.2。
AGAIN: SETB P1.2 ACALL DELAY CLR P1.2 ACALL DELAY SJMP AGAIN
单比特指令
指示 | 功能 |
---|---|
设置位 | 设置位(位 = 1) |
清除位 | 清除该位(位 = 0) |
CPL位 | 对位取反(位=非位) |
JB位,目标 | 如果位= 1则跳转到目标(如果位则跳转) |
JNB 位,目标 | 如果位 = 0 则跳转到目标(如果没有位则跳转) |
JBC 位,目标 | 如果位 = 1,则跳转到目标,清除位(如果位则跳转,然后清除) |
嵌入式系统 - 术语
程序计数器
程序计数器是一个 16 位或 32 位寄存器,其中包含下一条要执行的指令的地址。每次获取指令时,PC 都会自动递增到下一个连续的内存位置。分支、跳转和中断操作将下一个顺序位置以外的地址加载到程序计数器中。
激活上电复位将导致寄存器中的所有值丢失。这意味着 PC(程序计数器)的值在复位时为 0,迫使 CPU 从 ROM 存储位置 0000 获取第一个操作码。这意味着我们必须将上行代码的第一个字节放在 ROM 位置 0000,因为那是CPU期望找到第一条指令
重置向量
复位向量的重要性在于它将处理器指向包含固件第一条指令的内存地址。如果没有复位向量,处理器将不知道从哪里开始执行。复位后,处理器将预定义内存位置的复位向量值加载到程序计数器 (PC)。在 CPU08 架构上,它位于 $FFFE:$FFFF 位置。
当不需要重置向量时,开发人员通常认为这是理所当然的,并且不会将其编程到最终图像中。因此,处理器不会在最终产品上启动。这是调试阶段发生的常见错误。
堆栈指针
堆栈在 RAM 中实现,CPU 寄存器用于访问它,称为 SP(堆栈指针)寄存器。SP 寄存器是一个 8 位寄存器,可寻址范围为 00h 至 FFh 的存储器地址。最初,SP 寄存器包含值 07,指向位置 08,作为 8051 用于堆栈的第一个位置。
当CPU寄存器的内容存储在堆栈中时,称为PUSH操作。当堆栈的内容存储到CPU寄存器中时,称为POP操作。换句话说,寄存器被压入堆栈以保存它,并从堆栈中弹出以检索它。
无限循环
无限循环或无限循环可以被识别为计算机程序中在循环中无限执行的指令序列,原因如下 -
- 没有终止条件的循环。
- 具有永远无法满足的终止条件的循环。
- 具有导致循环重新开始的终止条件的循环。
这种无限循环通常会导致较旧的操作系统变得无响应,因为无限循环会消耗所有可用的处理器时间。等待用户输入的 I/O 操作也称为“无限循环”。计算机“冻结”的一个可能原因是无限循环。其他原因包括死锁和访问冲突。
与 PC 不同,嵌入式系统永远不会“退出”应用程序。它们通过无限循环闲置,等待以中断或预调度任务的形式发生的事件。为了节省电量,某些处理器会进入特殊的睡眠或等待模式,而不是通过无限循环闲置,但它们会根据计时器或外部中断退出此模式。
中断
中断主要是指示程序发生事件的硬件机制。它们可能随时发生,因此与程序流异步。它们需要处理器进行特殊处理,并最终由相应的中断服务例程(ISR)处理。需要快速处理中断。如果您花费太多时间来服务中断,那么您可能会错过另一个中断。
小端与大端
尽管数字总是以相同的方式显示,但它们在内存中的存储方式并不相同。Big-Endian 机器将数据的最高有效字节存储在最低内存地址中。Big-Endian 机器将 0x12345678 存储为 -
ADD+0: 0x12 ADD+1: 0x34 ADD+2: 0x56 ADD+3: 0x78
另一方面,Little-Endian 机器将数据的最低有效字节存储在最低内存地址中。Little-Endian 机器将 0x12345678 存储为 -
ADD+0: 0x78 ADD+1: 0x56 ADD+2: 0x34 ADD+3: 0x12
嵌入式系统 - 汇编语言
开发汇编语言是为了为机器级代码指令提供助记符或符号。汇编语言程序由助记符组成,因此应将它们翻译成机器代码。负责这种转换的程序称为汇编程序。汇编语言通常被称为低级语言,因为它直接与 CPU 的内部结构一起工作。要使用汇编语言进行编程,程序员必须了解CPU的所有寄存器。
不同的编程语言,如 C、C++、Java 和各种其他语言被称为高级语言,因为它们不处理 CPU 的内部细节。相反,汇编器用于将汇编语言程序翻译成机器代码(有时也称为目标代码或操作码)。类似地,编译器将高级语言翻译成机器代码。例如,要用C语言编写程序,必须使用C编译器将程序翻译成机器语言。
汇编语言的结构
汇编语言程序是一系列语句,这些语句要么是 ADD 和 MOV 等汇编语言指令,要么是称为指令的语句。
指令告诉 CPU 要做什么,而伪指令(也称为伪指令)则向汇编器提供指令。例如,ADD和MOV指令是CPU运行的命令,而ORG和END是汇编指令。当使用 ORG 伪指令时,汇编器将操作码放置到内存位置 0,而 END 表示源代码的结束。程序语言指令由以下四个字段组成 -
[ label: ] mnemonics [ operands ] [;comment ]
方括号 ([]) 表示该字段是可选的。
标签字段允许程序通过名称引用一行代码。标签字段不能超过一定的字符数。
助记符和操作数字段一起执行程序的实际工作并完成任务。像 ADD A , C & MOV C, #68 这样的语句,其中 ADD 和 MOV 是助记符,它们产生操作码;“A,C”和“C,#68”是操作数。这两个字段可以包含指令。指令不生成机器代码,仅由汇编器使用,而指令则被翻译成机器代码供 CPU 执行。
1.0000 ORG 0H ;start (origin) at location 0 2 0000 7D25 MOV R5,#25H ;load 25H into R5 3.0002 7F34 MOV R7,#34H ;load 34H into R7 4.0004 7400 MOV A,#0 ;load 0 into A 5.0006 2D ADD A,R5 ;add contents of R5 to A 6.0007 2F ADD A,R7 ;add contents of R7 to A 7.0008 2412 ADD A,#12H ;add to A value 12 H 8.000A 80FE HERE: SJMP HERE ;stay in this loop 9.000C END ;end of asm source file
评论字段以分号开头,分号是评论指示符。
注意程序中的标签“HERE”。任何引用指令的标签后面都应该跟一个冒号。
汇编和运行 8051 程序
这里我们将讨论汇编语言的基本形式。创建、汇编和运行汇编语言程序的步骤如下 -
首先,我们用编辑器输入一个与上面的程序类似的程序。所有 Microsoft 操作系统附带的编辑器(如 MS-DOS EDIT 程序)可用于创建或编辑程序。编辑器必须能够生成 ASCII 文件。源文件的“asm”扩展名将在下一步中由汇编器使用。
“asm”源文件包含步骤 1 中创建的程序代码。它被输入到 8051 汇编器。然后,汇编器将汇编语言指令转换为机器代码指令,并生成.obj 文件(目标文件)和.lst 文件(列表文件)。它也称为源文件,这就是为什么一些汇编器要求该文件具有“src”扩展名的原因。“lst”文件是可选的。它对程序非常有用,因为它列出了所有操作码和地址以及汇编器检测到的错误。
汇编程序需要第三步,称为链接。链接程序采用一个或多个目标文件并生成扩展名为“abs”的绝对目标文件。
接下来,“abs”文件被输入到名为“OH”(对象到十六进制转换器)的程序,该程序创建一个扩展名为“hex”的文件,准备烧录到 ROM 中。
数据类型
8051微控制器包含8位的单一数据类型,并且每个寄存器也是8位大小。程序员必须分解大于 8 位的数据(00 到 FFH,或十进制的 255),以便 CPU 可以处理。
DB(定义字节)
DB 指令是汇编器中使用最广泛的数据指令。它用于定义8位数据。它还可用于定义十进制、二进制、十六进制或 ASCII 格式的数据。对于十进制,十进制数后面的“D”是可选的,但对于“B”(二进制)和“Hl”(十六进制)是必需的。
要表示 ASCII,只需将字符放在引号中(“像这样”)。汇编器自动生成数字/字符的 ASCII 代码。DB 指令是唯一可用于定义大于两个字符的 ASCII 字符串的指令;因此,它应该用于所有 ASCII 数据定义。下面给出了 DB 的一些示例 -
ORG 500H DATA1: DB 28 ;DECIMAL (1C in hex) DATA2: DB 00110101B ;BINARY (35 in hex) DATA3: DB 39H ;HEX ORG 510H DATA4: DB "2591" ;ASCII NUMBERS ORG 520H DATA6: DA "MY NAME IS Michael" ;ASCII CHARACTERS
ASCII 字符串可以使用单引号或双引号。DB 还用于以字节大小的块分配内存。
汇编指令
8051 的一些指令如下 -
ORG (origin) - origin 指令用于指示地址的开头。它采用十六进制或十进制格式的数字。如果在数字后提供 H,则该数字被视为十六进制,否则被视为十进制。汇编器将十进制数转换为十六进制数。
EQU(等于) - 用于定义常量而不占用内存位置。EQU 将一个常量值与一个数据标签关联起来,以便该标签出现在程序中,其常量值将替代该标签。当执行指令“MOV R3,#COUNT”时,寄存器R3将被加载值25(注意#符号)。使用EQU的优点是程序员可以改变它一次,而汇编器将改变它出现的所有地方;程序员不必搜索整个程序。
END 指令- 它指示源(asm)文件的结尾。END指令是程序的最后一行;END 伪指令之后的任何内容都会被汇编器忽略。
汇编语言中的标签
汇编语言中的所有标签必须遵循以下规则 -
每个标签名称必须是唯一的。汇编语言编程中用于标签的名称由大写和小写字母、数字 0 到 9 以及特殊字符组成,例如问号 (?)、句点 (.)、@、下划线 (_)、和美元($)。
第一个字符应为字母字符;它不能是一个数字。
保留字不能用作程序中的标签。例如,ADD 和 MOV 字是保留字,因为它们是指令助记符。
嵌入式系统 - 寄存器
寄存器在CPU中用于临时存储信息,这些信息可以是要处理的数据,或者是指向要获取的数据的地址。在8051中,有一种数据类型是8位,从MSB(最高有效位)D7到LSB(最低有效位)D0。对于 8 位数据类型,任何大于 8 位的数据类型在处理之前都必须分解为 8 位块。
8051最广泛使用的寄存器是A(累加器)、B、R0-R7、DPTR(数据指针)和PC(程序计数器)。除 DPTR 和 PC 外,所有这些寄存器都是 8 位的。
8051中的存储寄存器
我们将在这里讨论以下类型的存储寄存器 -
- 累加器
- R寄存器
- B寄存器
- 数据指针(DPTR)
- 程序计数器(PC)
- 堆栈指针 (SP)
累加器
累加器(寄存器 A)用于所有算术和逻辑运算。如果累加器不存在,则每次计算(加法、乘法、移位等)的每个结果都将存储到主存储器中。对主存储器的访问比对累加器等寄存器的访问慢,因为用于大主存储器的技术比用于寄存器的技术慢(但便宜)。
“R”寄存器
“R”寄存器是一组八个寄存器,即R0、R1 至R7。这些寄存器在许多操作中充当辅助或临时存储寄存器。考虑 10 和 20 之和的示例。将变量 10 存储在累加器中,将另一个变量 20 存储在寄存器 R4 中。要处理加法运算,请执行以下命令 -
ADD A,R4
执行该指令后,累加器将包含值30。因此“R”寄存器是非常重要的辅助或帮助寄存器。如果没有这些“R”寄存器,累加器本身不会很有用。“R”寄存器用于临时存储值。
让我们再举一个例子。我们将 R1 和 R2 中的值相加,然后从结果中减去 R3 和 R4 的值。
MOV A,R3 ;Move the value of R3 into the accumulator ADD A,R4 ;Add the value of R4 MOV R5,A ;Store the resulting value temporarily in R5 MOV A,R1 ;Move the value of R1 into the accumulator ADD A,R2 ;Add the value of R2 SUBB A,R5 ;Subtract the value of R5 (which now contains R3 + R4)
正如你所看到的,我们使用R5来暂时保存R3和R4的和。当然,这不是计算 (R1 + R2) – (R3 + R4) 的最有效方法,但它确实说明了使用“R”寄存器作为临时存储值的方法。
“B”寄存器
“B”寄存器与累加器非常相似,因为它可以保存 8 位(1 字节)值。“B”寄存器仅由两条 8051 指令使用:MUL AB和DIV AB。要快速轻松地将 A 乘以或除以另一个数字,您可以将另一个数字存储在“B”中并使用这两个指令。除了使用 MUL 和 DIV 指令之外,“B”寄存器还经常用作另一个临时存储寄存器,很像第九个 R 寄存器。
数据指针
数据指针 (DPTR) 是 8051 唯一用户可访问的 16 位(2 字节)寄存器。累加器、R0–R7 寄存器和 B 寄存器是 1 字节值寄存器。DPTR 旨在指向数据。8051 使用 DPTR 指示的地址来访问外部存储器。DPTR 是唯一可用的 16 位寄存器,通常用于存储 2 字节值。
程序计数器
程序计数器(PC)是一个 2 字节地址,它告诉 8051 在内存中可以找到下一条要执行的指令。当 8051 初始化时,PC 从 0000h 开始,并在每次执行指令后递增。PC并不总是加1。有些指令可能需要2或3个字节;在这种情况下,PC 将增加 2 或 3。
分支、跳转和中断操作将下一个顺序位置以外的地址加载到程序计数器中。激活上电复位将导致寄存器中的所有值丢失。这意味着复位时 PC 的值为 0,迫使 CPU 从 ROM 位置 0000 获取第一个操作码。这意味着我们必须将上行码的第一个字节放在 ROM 位置 0000,因为这是 CPU 期望找到的位置。第一条指令。
堆栈指针 (SP)
与除 DPTR 和 PC 之外的所有寄存器一样,堆栈指针可以保存 8 位(1 字节)值。堆栈指针指示要从堆栈中删除下一个值的位置。当一个值被压入堆栈时,SP 的值会递增,然后该值将存储在结果内存位置。当一个值从堆栈中弹出时,该值从 SP 指示的内存位置返回,然后 SP 的值递减。
这个操作顺序很重要。当8051初始化时,SP将被初始化为07h。如果同时将一个值压入堆栈,则该值将存储在内部 RAM 地址 08h 中,因为 8051 将首先递增 SP 的值(从 07h 到 08h),然后将压入的值存储在该内存中地址(08h)。SP 由 8051 通过 6 个指令直接修改:PUSH、POP、ACALL、LCALL、RET 和 RETI。
8051中的ROM空间
8051系列的一些成员只有4K字节的片内ROM(例如8751、AT8951);有些具有8K ROM,如AT89C52,还有一些家族成员具有32K字节和64K字节片上ROM,如Dallas Semiconductor。需要记住的一点是,8051 系列的任何成员都不能访问超过 64K 字节的操作码,因为 8051 中的程序计数器是 16 位寄存器(0000 到 FFFF 地址)。
8051 内部程序 ROM 的第一个位置的地址为 0000H,而最后一个位置可能会有所不同,具体取决于芯片上 ROM 的大小。在 8051 系列成员中,AT8951 具有 $k 字节的片上 ROM,其存储器地址为 0000(第一个位置)到 0FFFH(最后一个位置)。
8051 标志位和 PSW 寄存器
程序状态字(PSW)寄存器是一个8位寄存器,也称为标志寄存器。它是8位宽,但只使用了6位。两个未使用的位是用户定义的标志。其中四个标志称为条件标志,这意味着它们指示执行指令后产生的条件。这四个是CY(进位)、AC(辅助进位)、P(奇偶校验)和OV(溢出)。RS0 和 RS1 位用于更改组寄存器。下图显示了程序状态字寄存器。
PSW 寄存器包含反映 CPU 当前状态的状态位。
CY | CA | F0 | RS1 | RS0 | OV | - | 磷 |
---|
CY | PSW.7 | 携带旗帜 |
交流电 | PSW.6 | 辅助进位标志 |
F0 | PSW.5 | 标志 0 可供用户用于一般用途。 |
RS1 | PSW.4 | 寄存器组选择器位 1 |
RS0 | PSW.3 | 寄存器组选择器位 0 |
OV | PSW.2 | 溢出标志 |
- | PSW.1 | 用户可定义的标志 |
磷 | PSW.0 | 奇偶校验标志。在指令周期内由硬件置位/清零,以指示累加器中 1 位的偶数/奇数。 |
我们可以使用 RS0 和 RS1 位选择相应的寄存器组位。
RS1 | RS2 | 注册银行 | 地址 |
---|---|---|---|
0 | 0 | 0 | 00H-07H |
0 | 1 | 1 | 08H-0FH |
1 | 0 | 2 | 10点-17点 |
1 | 1 | 3 | 18H-1FH |
CY,进位标志- 每当 D7 位有进位输出时,该进位标志就被置位 (1)。它在 8 位加法或减法运算后受到影响。也可以通过“SETB C”和“CLR C”等指令直接将其重置为1或0,其中“SETB”代表设置位进位,“CLR”代表清除进位。
AC,辅助进位标志− 如果在 ADD 或 SUB 操作期间有来自 D3 和 D4 的进位,则 AC 位被设置;否则,它被清除。它用于执行二进制编码的十进制算术运算的指令。
P,奇偶校验标志- 奇偶校验标志仅表示累加器寄存器中 1 的数量。如果A寄存器包含奇数个1,则P = 1;对于偶数个 1,P = 0。
OV,溢出标志- 当有符号数运算的结果太大导致高位溢出到符号位时,该标志被设置。它仅用于检测有符号算术运算中的错误。
例子
显示以下指令中添加 9CH 和 64H 后 CY、AC 和 P 标志位的状态。
MOV A,#9CH
添加A,#64H
Solution: 9C 10011100 +64 01100100 100 00000000 CY = 1 since there is a carry beyond D7 bit AC = 0 since there is a carry from D3 to D4 P = 0 because the accumulator has even number of 1's
嵌入式系统 - 寄存器组/堆栈
8051 微控制器共有 128 字节 RAM。我们将讨论这 128 字节 RAM 的分配,并检查它们作为堆栈和寄存器的用法。
8051 中的 RAM 内存空间分配
8051内部的128字节RAM被分配地址00到7FH。它们可以作为内存位置直接访问,并分为三个不同的组,如下所示 -
从 00H 到 1FH 位置的 32 个字节被预留给寄存器组和堆栈。
从 20H 到 2FH 位置的 16 个字节被预留用于位寻址读/写存储器。
30H到7FH位置的80个字节用于读写存储;它被称为便签本。这 80 个位置的 RAM 广泛用于 8051 程序员存储数据和参数。
在 8051 中注册银行
总共为寄存器组和堆栈预留了 32 字节的 RAM。这 32 个字节被分为 4 个寄存器组,每个寄存器组有 8 个寄存器,R0–R7。RAM 位置从 0 到 7 被预留给 R0–R7 的存储体 0,其中 R0 是 RAM 位置 0,R1 是 RAM 位置 1,R2 是位置 2,依此类推,直到内存位置 7,属于存储体的 R7 0。
第二组寄存器 R0–R7 从 RAM 位置 08 开始,到达位置 OFH。R0–R7 的第三组从内存位置 10H 开始,一直到位置 17H。最后,RAM 位置 18H 到 1FH 为第四组 R0–R7 预留。
默认寄存器库
如果 RAM 位置 00-1F 预留给四个寄存器组,那么当 8051 上电时我们可以访问 R0-R7 的哪个寄存器组?答案是寄存器组0;也就是说,在对 8051 进行编程时,使用名称 R0 到 R7 来访问从 0 到 7 的 RAM 位置。因为通过名称(例如 R0 到 R7)引用这些 RAM 位置比通过它们的内存位置引用这些 RAM 位置要容易得多。
如何切换注册库
当 8051 上电时,寄存器组 0 是默认值。我们可以使用 PSW 寄存器切换到其他库。PSW 的 D4 和 D3 位用于选择所需的寄存器组,因为它们可以通过位寻址指令 SETB 和 CLR 访问。例如,“SETB PSW.3”将设置 PSW.3 = 1 并选择存储体寄存器 1。
RS1 | RS2 | 银行选择 |
---|---|---|
0 | 0 | 银行0 |
0 | 1 | 银行1 |
1 | 0 | 银行2 |
1 | 1 | 银行3 |
堆栈及其操作
8051 中的堆栈
堆栈是 RAM 的一部分,CPU 使用它临时存储数据或内存地址等信息。考虑到寄存器数量有限,CPU 需要这个存储区域。
如何访问堆栈
由于堆栈是 RAM 的一部分,因此 CPU 内部有寄存器指向它。用于访问堆栈的寄存器称为堆栈指针寄存器。8051中的堆栈指针是8位宽,可以取00到FFH的值。当8051初始化时,SP寄存器包含值07H。这意味着 RAM 位置 08 是用于堆栈的第一个位置。将 CPU 寄存器存储到堆栈中的操作称为PUSH,将堆栈中的内容取回 CPU 寄存器的操作称为POP。
压入堆栈
在 8051 中,堆栈指针 (SP) 指向堆栈最后使用的位置。当数据压入堆栈时,堆栈指针(SP)加1。执行PUSH时,寄存器的内容保存在堆栈上,SP加1。要将寄存器压入堆栈,我们必须使用它们的 RAM 地址。例如,指令“PUSH 1”将寄存器R1压入堆栈。
从堆栈中弹出
将堆栈内容弹出回给定寄存器与压入过程相反。每次弹出操作时,堆栈的顶部字节都会复制到指令指定的寄存器,并且堆栈指针会递减一次。
嵌入式系统 - 说明
程序流程以顺序方式进行,从一条指令到下一条指令,除非执行控制转移指令。汇编语言中的各种类型的控制转移指令包括条件或无条件跳转和调用指令。
循环和跳转指令
在8051中循环
将指令序列重复一定次数称为循环。指令DJNZ reg, label用于执行循环操作。该指令中,寄存器减1;如果不为零,则 8051 跳转到标签引用的目标地址。
寄存器中加载了循环开始之前的重复次数计数器。在该指令中,寄存器递减和跳转决定被组合成一条指令。寄存器可以b