单片机

进制转换及其加减法,补码

2,4,88,10,16进制之间的相互转化,具体内容见逻辑设计

数学基础知识

  1. 数据大小

    1. 储存容量是衡量微机内部储存器能储存二进制(Bit)信息量大小的一个技术指标

    2. 8位二进制数据称为一个字节(Byte)——最基本的计量单位,记为1B

    3. 16位二级制数据称为一个字(word)

    4. 32位二进制数据称为一个双字(Dword)

  2. 只读存储器(ROM)

    ROM是一种掉电后不丢失信息的储存器。由于这个原因,ROM也成为非易失性存储器。

     

    结构和容量

    给定储存器芯片有12个地址引脚和4个数据引脚,此储存芯片有4096个位置($2^{12}=4096$),每个位置能储存4位数据,所以结构就是4096×4,也常用4K×4表示。其容量是16Kb,因为总共是4K个位置,每个位置能保存4位数据

     

    一个容量是512K储存器芯片有8个数据引脚,请找出:(a)组织结构;(b)这个储存芯片的地址引脚数

    (a)8个数据引脚可以保存8位数据,为了找出这个储存器芯片的位置数,需要用数据引脚数去除容量。512K/8=64K;所以储存芯片的组织结构是64K×8

    (b)芯片有16根地址线,因为$2^{16}=64K$

  3. 随机访问储存器(RAM)

    储存计算机运行中暂停的项目,当电脑关机时数据会丢失

  4. 总线设计

    image-20231019221602733

    1. 地址总线

      cpu地址总线的数目决定了能与cpu进行通信的位置数,位置数通常等于$2^x$,x是地址线的数目。

      每个位置最多可以有一个字节的数据,不用考虑数据总线的大小。

      地址总线是单向的。

      地址总线使用得越多,外设使用越多。

    2. 数据总线

      数据总线是双向的,因为CPU需要使用它们接收和发送数据。使用的数据总线越多,CPU效率越高。

    3. 控制总线

      向设备提供读取或写入信号,以提示CPU是否正在请求信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
		ORG	0
MOV R0, #66H
MOV R3, #7FH
MOV R7, #5DH
PUSH 0
PUSH 3
PUSH 7
CLR A
MOV R3, A
MOV R7, A
POP 3
POP 7
POP 0
END

pop代表把栈顶的值赋值给r几

例如pop 3就是把栈顶的值赋值给R3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
		ORG	0
MOV SP, #70H
MOV R5, #66H
MOV R2, #7FH
MOV R7, #5DH
PUSH 5
PUSH 2
PUSH 7
CLR A
MOV R2, A
MOV R7, A
POP 7
POP 2
POP 5
END

&nbsp

8051系统概述

8051控制器的内部框图

image-20231019213820890

8501的主要特性

特性 数量
ROM 4KB
RAM 128KB
定时器 2
I/O引脚 32
串行端口 1
中断源 6

8051及其成员对比

特性 8051 8052 8031
ROM 4KB 8K 0K
RAM 128KB 256KB 128KB
定时器 2 3 2
I/O引脚 32 32 32
串行端口 1 1 1
中断源 6 8 6

 

 

大多数的8051单片机的寄存器是8位的,所以也叫8051为8位单片机

image-20231019195634248

8051中常用的寄存器有A(累加器)、B、RO、R1、R2、R3、R4、R5、R6、R7、DPTR(数据指针)以及PC(程序计数器)寄存器。除DPTR和程序计数器是16位外,以上寄存器都是8位。

 

MOV指令

1
MOV 目的操作数,源操作数

image-20231019200313361

1.可直接将数值装载到A、B或R0~R7的任意意一个寄存器当中。然而,为表示装载的是立即数,必须在数值前加上符号(#),如下:

2.如果将0~F的值装载到8位寄存器中,则其余的位就默认为0.例如,对于指今MOV  A,#5”而言,结果是A=05,用二进制表示就是A=00000101。

3.装载太大的值到寄存器中时会出错。(装载的值超过八位)

4.将数值装载到寄存器中时,必须在数值前加上符号(#),否则就表示装载的是存储器中的数。例如,MOV  A,17H”指令代表的就是将存储单元17H中的数装载到A中,结果就是任意值。

 

ADD指令

1
ADD A,源操作数;

指令中的源操作数即可以是寄存器,也可以是立即数;

寄存器A必须存在于任何的算数运算中,但其只能是任何算术运算中的目的操作数而不能是源操作数。

 

8051汇编语言简介

1.汇编语言程序由一连串的汇编指令组成

2.一条汇编指令由4个字段组成

1
[标签:]  助记符  [操作数]  [;注释] 

助记符即为指令

image-20231019201422708

3.方框号代表里面的字段是可选的,不是每条指令都必须包含

4.ADD和MOV就是助记符,即产生操作码的部分。ORG和END就是伪代码(指示符),这些指示符不产生任何机器代码(操作码),仅供汇编使用。

 

8051中的程序计数器和ROM空间

image-20231019202019120

1.编写汇编语言需要将汇编程序写好写入asm文件中

2.asm源文件被送入8051汇编器,汇编器将指令换成机器代码,然后产生目标文件(obj)和列表(lst)文件

image-20231019202418301

3.汇编器的第三步是链接:链接程序接受一个或多个目标文件并生成带有扩展名”abs”的绝对目标文件

4.将“abs”文件送入名为”OH”的程序(目标文件转16进制)中,从而产生即将烧入ROM中的扩展名位”hex”的文件。

  • DOS EDIT编辑器产生asm文件
  • 8051编译器产生obj和lst文件
  • 链接器程序产生abs文件
  • OH程序产生HEX文件

 

8051中的程序计数器和ROM空间

8051中的程序计数器(PC)

  1. 程序计数器指向下一条将执行指令的地址。
  2. 当CPU从程序ROM中得到操作码时,程序计数器就会自动增加并指向下一条指令
  3. 8051中的程序计数器为16位,能访问的程序地址范围是0000H~FFFFH,共64KB代码。

上电8051唤醒的位置

  1. 当上电后,8051程序计数器中的值就是0000,就表示第一个操作码存储在ROM地址0000H中。
  2. 8051系统中,第一个操作码就必须烧人程序ROM的存储位置0000H中,因为这是启动后它寻找第一条指令的位置。

 

8051数据类型和指令

BD

DB指令是汇编器中使用最广泛的数据指示符之一,它用于定义8位数据。

十进制后面的D是可选的,但是二进制的B和十六进制的H是必须加的。

image-20231019204830206

汇编指示符

1.ORG:用于ROM中表示起始地址

2.EQU:用于定义常量,但是不占用系统空间

3.END:告诉汇编器源文件(asm)末尾所处的位置。END指令是8051程序的最后一位,意味着END指令之后的源代码都会被汇编器忽略。

 

8051标志位和PSW寄存器

8051中也有表示算数运算状态的标志寄存器,如进位标志

8051中的标志寄存器叫做程序状态字(PSW)寄存器

PSW(程序状态字)寄存器

PSW寄存器是一个8位寄存器,也叫标志寄存器,但是在8051中,PSW只用了6位,剩余两位是用户自定义标志位。

6为中有4位是状态标志位也就是一些指令执行后的结果状态,分别是CY(进位)、AC(辅助进位)、P(奇偶校验位)以及OV(溢出位)

PSW.3和PSW.4位被分别设计为了RS0和RS1,用于选择组寄存器。

image-20231019210419646

PSW.5和PSW.1是通用状态标志位,供程序员使用。

名称 位置 解释
CY PSW.7 进位标志
AC PSW.6 辅助进位标志
F0 PSW.5 可用于用户的通用目的
RS1 PSW.4 寄存器组选择器位1
RS0 PSW.3 寄存器组选择器位0
OV PSW.2 溢出标志
PSW.1 用户可定义位
P PSW.0 奇偶标志。通过硬件每条指令周期设置/清0 来指明是累加器中的奇/偶位数。

image-20231019210748792

 

ADD指令和PSW

分析ADD指令对PSW寄存器中CY、AC以及P标志位的影响。

1
2
MOV A,#38H
MOV A,#2FH

image-20231020151833345

相加之后:CY=0,因为D7位没有进位。

AC=1,因为有来自D3到D4位的进位

P=1,因为累加器有奇数个1(5个1)

 

8051寄存器组和栈

8051微控制器中共有128个字节的RAM

8051中的RAM存储分配

8051中有128个字节的RAM(一些成员,如8052,有256个字节的RAM),其所分配的地址范围是00~7FH。它们可直接作为存储器位置进行访问。这128个字节可分成如下三部分:

  1. 从00至1F(十六进制)共有32个字节用于寄存器组和栈
  2. 从20H至2FH共有16个字节用于位可寻址读/写存储器。
  3. 从30H至7FH共有80个字节用于读/写存储,也通常称为高速暂存器(scratch pad)。这80个RAM位置被8051程序员广泛应用于存储数据以及相关参数中。

image-20231020152516334

第一组寄存器与栈使用的是同样的RAM空间。这点在8051编程时尤其要注意,要么回避使用第第一组寄存器,要要么分配另一块RAM区域给栈。

image-20231020152841693

 

默认寄存器组

如果RAM位置00~1F地址被用于四个寄存器组,那么上电后可以访问的R0~R7的寄存器组就是寄存器组0也就是说,当编写8051程序时,RAM位置0、1、2、3、4、5、6和7分别被名字为R0、R1、R2、R3、R4、R5、R6以及R7的符号进行访问。使用R0、R1等名字来访问RAM位置地址相比于用存储器位置访问容易得多。

 

如何切换寄存器组

8051上电后,默认寄存器组的是寄存器组0.但我们可以通过使用PSW寄存器切换到其他的寄存器组。PSW的D4位和D3位用于选择需要的寄存器组.。

image-20231019210748792

 

8051中的堆

栈是RAM中的一段空间,为CPU暂时存储信息。这些信息可以是数据或是地址。CPU需要该存储区域是因为寄存器数目有限。

 

8051如何访问栈

​ 如果栈是RAM的一段空间,CPU中就必须有指向这段空间的寄存器。用于访问栈的寄存器称为SP(栈指针)寄存器。8051中的栈指针仅8位宽,这就意味能得到的值的范围是00~FFH。

​ 当8051上电后,SP寄存器的值是07(因为默认寄存器组1的第一位为8),就意味着RAM位置08是8051栈的第一个位置。

​ 将CPU寄存器中的值存人栈称为PUSH(压栈),从栈中取出值放入寄存器中称为POP(出栈),也就是说,一个寄存器被压人栈中就是保存数据,而从栈中弹出则是重新得到该数据。当进行压栈和出栈的操作时,SP的作用很重要。

 

压栈(push)

在8051中,栈指针指向栈的最后一个位置。如果将数据压入栈中,栈指针就自增1。

例如:PUSH 1;就是将R1中的数据压入堆栈中(第一次位置为08,压入后的位置是09)

1
2
3
4
5
6
MOV	R6,#25H
MOV R1,#12H
MOV R4,#0F3H
PUSH 6
PUSH 1
PUSH 4

image-20231020154319025

出栈(POP)

​ 每次弹出时,栈顶的字节会压入到所写寄存器中,同时栈指针自减一次。

​ 例如:POP 3;就是将栈顶指针对应的字节压入R3中。

image-20231020154538961

 

栈上限

​ 8051的RAM位置地址范围08~1F用于栈,这是因为RAM位置地址20-2FH只能用于位可寻址存储,而不能用于栈。

​ 如果某程序需要大于24字节(08~1FH=24字节)的栈,则可以改变SP指向RAM中30~7FH的位置。完成此操作的指令是:MOV  SP,#xx

 

栈和寄存器组1的冲突

默认的寄存器组为寄存器0,默认栈的起始点为寄存器1的R0。

寄存器组1和栈使用的是同样的存储空间。如果一个程序需要使用寄存器组1和组2时,就必须重新分配RAM空间给栈。例如,可分配RAMM位置地址60H甚至更高的位置地址给栈。

1
2
3
4
5
6
7
8
MOV	SP,#5FH;RAM位置地址60H,即栈的第一个位置

MOV R2,#25H
MOV R1,#12H
MOV R4,#0F3H
PUSH 2
PUSH 1
PUSH 4

image-20231020160228129

提高CPU效率的方法

微处理器设计者可使用三种方法来提高CPU的处理效率。

  1. 增加芯片的时钟频率。这种方法的缺点是:频率越高,则功耗和热损耗就越大,功耗和散热对掌上型设备尤其是大问题。
  2. .通过增加导线成为哈佛体系结构,从而将更多的信息(代码和数据)装载到CPU中处理。而在x86和一些通用微处理器中,哈佛体系结构价格昂贵且不切实际,但是在今天的单芯片计算机中(微控制器),这已不是问题。
  3. 改变CPU的内部结构,使用RISC结构。

 

跳转、循环和调用指令

8051中的循环

​ 在8051中,循环操作通过指令“DJNZ  reg,label”来实现。该指令中,寄存器递减,如果非零,则跳转至标签所示的目标地址。在循环开始之前,寄存器预存人循环次数。

image-20231020164656061

上诉代码所实现的功能为:

  1. 累加器清零
  2. 将3加入累加器中10次

注意:上述代码以R2为累加器,而R2为8位寄存器,它能储存的最大值为FHH(十进制的255),因此每次循环的最多次数也为256,如需更多的循环则需要进行循环的嵌套。

循环嵌套

image-20231020165110399

上述代码实现的功能:

  1. 将数55H存入累加器ACC中
  2. 对累加器ACC执行700次取补码。

 

其他条件跳转指令

image-20231020165231702

注意:重点记忆JZJNC

 

所有的条件跳转指令都是短跳转指令

​ 必须指出,所有的条件跳转指令都是短跳转指令,也就是说,跳转指令的目标地址必须在程序计数器(PC)的-128~+127字节之内。

 

无条件跳转指令

无条件跳转指令是一种不需要任何条件,程序就可以跳转到目标地址的指令。

在8051中,这样的指令有两种:长跳转(LJMP)指令和短跳转(SJMP)指令

LJMP(长跳转指令)

它是一个3字节指令,其中第一个字节是操作码,第二个和第三个字节表示16位目标地址。2字节的目标地址允许程序在存储单元00000H~FFFFH中任意跳转。

SJMP(短跳转指令)

它是一个2字节指令,第一个字节是操作码,第二个字节是目标地址的相对跳转地址。相对跳转地址的范围为00H~FFH,相对跳转地址又分为前向跳转地址和后向跳转地址,即在相对于当前PC地址的-128~+127字节存储器范围内。如果是前向跳转地址,则目标地址可以在距当前PC的127字节范围内;如果是后向跳转地址,则目标地址可以在距当前PC的-128字节范围内。

 

 

调用指令

​ 另一个控制跳转指令是CALL指令,该指令用于调用子程序。子程序常用于完成经常实现的任务。这样做不仅可以节省存储器空间,而且让程序更加结构化。在8051系列中,有两种调用指令:长调用(LCALL)指令及绝对调用(ACALL)指令。

LCALL(长调用指令)

它是一个3字节指令,其中第一个字节是操作码,第二个和第三个字节是子程序人口地址。因此,长调用指令可以调用存放在8051中64KB程序存储器任意位置的子程序。

为保证8051在调用子程序执行结束后能够知道返回到哪里并继续执行,处理器自动将长跳转指令的下一条指令地址保存到栈中。当一个子程序被调用时,控制器跳转到该子程序,并且处理器将PC值保存到栈中,同时开始获取一条新的指令地址。当子程序执行结束时,返回指令RET将控制器返回到调用位置。

==每一个子程序都需要一条返回指令作为结束。==

image-20231020170936284

RET指令的功能是将地址从栈中弹出并放入程序计数器中,从而恢复执行在CALL指令之后的指令。

 

ACALL(绝对调用指令)

由于ACALL是2字节指令,子程序的目标地址就必须在2KB字节范围内,这是因为2字节中只有11位表示地址。

 

8051芯片的延时

8051的机器周期

​ CPU执行指令时须花费一定的时钟周期,8051系列中,这些时钟周期就叫做机器周期(machine cycle,MC)。

​ 最原始的8051中,1个机器周期可占用12个振荡器(时钟)周期。因此,要想计算8051的机器周期,我们采用1/12的晶振频率,然后再取倒数。

image-20231020171851810

在一个时钟周期内,能运行的机器周期越多,当然效率就越高,如上图,从上到下机器运行的效率是逐渐增加的。

image-20231020172032002

 

8051的延时计算

image-20231020172335390

DELAY的子程序一般由两部分构成:

  1. 计数器设置
  2. 延时

增加延时时间的一种方式是在循环中使用NOP指令。NOP表示“空操作”,简单地浪费时间。

image-20231020172624264

循环内套用循环延时

image-20231020173008270

关于各种IC的延时计算

  1. 根据时钟周期与机器周期的比计算出,结合晶振频率计算出运行一个机器周期所需要的时间
  2. 计算延时函数中所运行机器周期的个数
  3. 如果是单个循环,则计算出的时间=循环所需的时间+循环外的指令运行时间;如果是嵌套循环,延时时间=内循环时间+外循环时间。它与所有其他延时循环一样,对它的延时计算只是约数,因为忽略了子程序的第一条及最后一条指令所产生的延时。

 

使用$符号和SSJMP表示跳转到自身

如果芯片中不存在要监视的程序,就需要使用跳转到自身指令使得微控制器不处于空闲状态。简单的做法是在JUMP后面写上$符号,代表跳转的位置也就是如下情况:

1
HERE:	SJMP	HERE

也可以如下使用:

1
SJMP	$

 

8051的I/O端口编程

image-20231020181205765

8051中一共有4个端口可以进行I/O操作,即P0-P3,每个端口有8个引脚。

8051有40个引脚,其中32个引脚属于4个端口,余下的引脚分别是$V_{cc}$​,GND,XTAL1,XTAL2,RST,EA,ALE/PROG和PSEN。

 

I/O端口引脚及其功能

所有端口在RESET(复位)时都配置成输入,并准备用作输入。

当第一个0写入某端口时,该端口便成为输出。若将该端口重新配置成输入,则必须将1送入该端口。若想将任何端口用做输入端口,则必须编程。

 

将个位读入进位标志

image-20231026195225266

读取输出端口锁存内容

有些指令读取的是内部端口锁存内容而不是外部引脚的状态。如“ANL & P1,A”,执行该指令时会产生如下一系列的动作:

1.读取端口内部锁存内容,并将该数据传送给CPU。

2.将这些数据与寄存器A中的内容相与。

3.结果写入端口锁存。
4.端口引脚数据改变,内容与端口锁存内容一致。

 

 

 

80511寻址方式

​ CPU可使用多种方式访问数据。数据可存放在寄存器、存储器中,或者以立即数的形式存在。访问这些数据的不同方法称为寻址方式(addressing modes)。

8051共提供5种寻址方式,如下:

1.立即寻址方式;
2.寄存器寻址方式;
3.直接寻址方式;
4.寄存器间接寻址方式;
5.变址寻址方式

 

立即寻址方式

直接将源操作数加载至任意寄存器,注意:立即数必须加前缀“#”

image-20231026200259601

寄存器寻址方式

寄存器寻址方式是将寄存器中的内容加载到另一个寄存器中,而不是操作数本身。如下所示:

image-20231026200404238

 

直接寻址方式

1.RAM地址00~1FH分配给寄存器组和栈。

2.RAM地址20-2FH用于位可寻址空间保存单点数据。

3.RAM地址30~7FH用于保存字节数据。

使用直接寻址方式可以访问RAM的128字节,但通常情况下它只访问RAM地址30~7FH空间,这是因为寄存器组位置由名为RO~R7的寄存器访问,而RAM中除了寄存器空间之外再没有对应的名字。

在直接寻址方式中,存放在RAM存储器中的数据对应的地址就是指令中给出的地址。而在立即寻址方式中,指令执行的数据就是操作数本身。是否有前缀“#”是两种寻址方式的主要区别。如下例所示(注意没有百“#标志):

image-20231026200609232

 

SFR寄存器

在8051单片机中,寄存器A、B、PSW和DPTR通常称为SFR(特殊功能寄存器)

关于SFR地址,需注意以下两点:
1.特殊功能寄存器地址范围是80H~FFH。地址大于80H的原因是00H~7FH地址属于8051内部RAM。
2.不是80H~FFH范围中的所有地址都用于SFR。未使用的保留,且不可被8051程序员使用。

 

寄存器间接寻址方式

在寄存器间接寻址方式中,寄存器可作为数据指针。若数据存在于CPU内部,则只能使用寄存器R0或R1将数据取出。当R0和R1用作指针保存RAM中的数据地址时,则须加上前级“@标志,如下所示:

image-20231026200946568

简单解释是将一个寄存器中数据的地址加载到另一个寄存器中。而不是数据本身。

如上,我们如果不佳@,那么就会将后面寄存器中的数据进行操作,而不是地址。

 

变址寻址方式

​ 变址寻址方式广泛用于访间8051单片机的ROM空间的查找表入口数据,指令是“MOVC  A,@A+DPTR”。16位的寄存器DPTR和寄存器A存放在片上ROM中的数据元素地址,因为数据元素存放在8051ROM代码区,所以使用指令MOV C,而不是MOV。“C”指代码。该指令将寄存器A中的内容与16位寄存器DPTR中的内容相加,形成所需数据的16位地址,如下所示:

image-20231026201652253

image-20231026201946030

 

算术逻辑指令与程序

在8051中,为了将数值相加,就必须使用累加器(寄存器A),ADD指令如下:

1
ADD A,源操作数;A = A + 源操作数

 

ADD指令

ADD指令的功能是将两个操作数相加,通常,目的操作数是寄存器A中的内容,而源操作数可以是立即数、寄存器中的内容或存储器中的内容。请记住,在8051汇编算术操作中不允许存储器-存储器式的操作。指令的执行将影响标志位AC、CY和P,这取决于执行的操作数。溢出标志位OV只有带符号数运算时才受影响。

image-20231026211723672

 

ADDC以及16位数加法

当两个16位的操作数相加时,需注意进位。指令ADDC(带进位加法指令)自的功能就是把源操作数的内容和进位标志CY都加入累加器A中。如下是3CE7H+3B8DH的相加操作:image-20231026212033413

 

DA指令

8051中的DA(十进制加法调整)指令用于解决两个BCD码相加不是BCD码的问题。助记符有一个操作数,就是累加器“A当有必要时,DA指令将6加入低位或高位,否则就不干涉结果。如下所示。

image-20231026212758013

DA操作总结

只能在ADD或ADDC指令执行之后才能执行。
1.若低位(4位)大于9,或AC=1,就将0110加入低4位。
2.若高位(4位)大于9,或CY=1,就将0110加入高4位。
事实上,AC(辅助进位)标志位除了用于纠正BCD加法之外,并无其他用处。例如,相加29H和18H,结果是41H,但这对于BDC码来说是错误的。

image-20231026212846867

无符号数相减

1
SUBB A,源操作数;A = A - 源操作数 -CY

SUBB(带借位减法),CY=0

算术减法中,8051微处理器(几乎涵盖所有的CPU)采用的是补码的方法。每个CPU中都包含加法电路,而因为减法电路的设计复杂(占用太多晶体管),因此8051使用加法电路来实现减法。如果8051执行减法指令时,须预设置CY=0。CPU硬件执行SUBB无符号数减法指令的步骤如下。
1.得到减数源操作数的补码。
2.将值与被减数(A)相加。
3.进位反相。

无符号数乘法和除法

1
MUL AB    ;AXB,将16位结果分别放入B和A

字节乘法中,其中一个操作数须放人寄存器A中,而另一个操作数则须放在寄存器B中,相乘后,结果分别放人寄存器A和B中,寄存器A保存低位字节,寄存器B保存高位字节。如下所示:225H与65H相乘的结果是16位数据,分别存入寄存器A和B中,如表所示。

image-20231026220940002

 

无符号数相除

字节相除时,分子必须放在寄存器A中,分母放在寄存器B中。除法指令完成之后,商存放入寄存器A中,余数存人寄存器B中。如下列代码和表6-3所示。

image-20231026221104566

 

CPL A(累加器取反)

此指令将寄存器内容的1变成0,反之亦然,所以称为取反(1’scomplement)。

image-20231026222810134

 

比较指令

8051中含有比较指令。语法如下:

1
CJNE 目的操作数,源操作数,相对地址