学习目的:通过具体的任务,了解单片机开发的过程。
涉及到的内容:
一、任务要求
指示灯LED4闪烁,亮0.5秒,灭0.5秒,无限循环。
二、针对于硬件的编程
1.确定原理图(清楚LED的硬件位置)
在实际的开发板上确定指示灯LED的实际位置

2.确定硬件上的物理关系(清楚LED的硬件连接关系)
在原理图上确定指示灯LED与单片机端口的连接关系

三、设计步骤
1.用我们自己的语言描述工作流程
1.1 指示灯LED4亮
1.2 延时0.5秒
1.3 指示灯LED4灭
1.4 延时0.5秒
1.5 跳转到1.1步
2.确定硬件连接关系,确定驱动逻辑
2.1 指示灯LED4→P1.5→反相器→限流电阻→指示灯的正极→,指示灯的负极接地
2.2 指示灯LED4亮
P1.5输出低电平,反相后为高电平,电压高于发光二极管的开启电压,亮
忽略掉其他信息,简单来描述,即 P1.5 = 0,亮
汇编语言实现:CLR P15 (清零)
2.2 指示灯LED4灭
P1.5输出高电平,反相后为低电平,电压低于发光二极管的开启电压,灭
忽略掉其他信息,简单来描述,即 P1.5 = 1,灭
汇编语言实现:SETB P15 (置位,把某一位变高)
3.延时子程序
实现方法
- 软件延时 与单片机相关 与指令执行周期相关(在工程中这种做法不可取)
- 硬件定时 与单片机相关 与硬件定时器相关 均与系统时钟相关
- 软硬结合 取长补短
软件延时
3.1 确定系统时钟

[补]周期指令

在51单片机中,执行一条指令的最小单元是12个时钟,即单片机的机器周期是由12个时钟周期构成的。
如果单片机的时钟是12MHz,则机器周期为1us。
3.2 确定指令周期数

这里与单片机的总线位宽有关,单片机的总线位宽是8位,即数据总线是8位,单片机一次只能处理一个字节,1字节可描述的无符号数为0-255。
具体执行过程:


DJNZ是双周期指令,即执行一次用2us。
该过程重复两次即可得到500us,涉及到循环执行。

将上述过程简化后的结果:

汇编语言里的子程序相当于C语言中的函数,子程序后需要有一个RET作为返回。
如何构建子程序?

四、完整的汇编指令

ORG不是汇编指令,是给编译器看的,ORG的作用是将下一条指令安排在所指地址中。

1.程序计数器PC


1)如何读取机器码

(单片机一次只能读取一个字节,这与单片机的总线位宽有关)
2)程序执行的方式
(分析指令和执行指令都是靠硬件电路实现的 )

若要对流程控制,则需要修改PC。
修改PC值的方法:

(没有直接修改PC的指令)

2.手工汇编
PC指针的初始值为0000H是由硬件电路决定的,单片机复位后PC值为0,所以程序的入口地址(程序的起始点)就是 0000H 地址。这里安排长跳转LJMP是为了预留出中断服务程序的入口地址。

1)LJMP指令执行的过程:

PC是从 0003H 变成 0100H,而不是从 0000H 变成 0100H。
2)SJMP指令执行过程:
查表可得SIMP的操作码为 80H
使PC值由 010CH 变为 0100H,也就是让 010CH 加上 XH 等于 0100H,即让 0100H 减去 010CH 即可得到 XH,但是短跳转只能提供8位的偏移量,X不可能等于 FFF4,所以翻译出的机器码为 F4H。
(PC是16位的,所以所有的运算都是按16位进行操作)

3)LCALL指令执行过程:
第一次长调用时PC值从 0105H 变成 0400H
第一次返回时PC值从 0408H 变成 0105H
第二次长调用时PC值从 010AH 变成 0400H
第二次返回时PC值从 0408H 变成 010AH

[补] 堆栈指针SP

51单片机的堆栈是向上生成,PC的默认值是07H,该单元永远用不到。
压栈的第一个数是PC的低八位,先保存低八位再保存高八位。

注:本文出自对bilibili 科大老孟手工汇编_004_程序执行过程 内容的学习笔记。