汇编程序与周期性任务设计

汇编程序与周期性任务设计

一、51单片机延时汇编语言

(一)指令周期,机器周期与时钟周期

1、指令周期

​ **指令周期:**执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。指令周期常常用若干个CPU周期数来表示,CPU周期也称机器周期。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。如:MOV为单周期,DJNZ为双周期

2、机器周期

机器周期:计算机中,常把一条指令的执行过程划分为若干个阶段,每一个阶段完成一项工作(例如,取指令、存储器读、存储器写等)。每一项工作称为一个基本操作,完成一个基本操作所需要的时间称为机器周期。它一般由12个时钟周期(振荡周期)组成,即由6个状态周期组成,而振荡周期=1/晶振频率,因此单片机的机器周期=12/晶振频率。如:12M晶振频率,机器周期为1微秒。

3、时钟周期

时钟周期也称为振荡周期,定义为时钟脉冲的倒数,时钟周期就是单片机外接晶振的倒数,是计算机中的最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作。时钟脉冲是计算机的基本工作脉冲,控制着计算机的工作节奏。时钟频率越高,工作速度就越快。如:12M的晶振,它的时钟周期就是1/12微秒。

(二)延时函数

1、单重循环短暂延时

​ 短暂延时可以通过单重循环来实现。例如,下面为延时200μs子程序。

DELAY:MOV R7,#100      ; 寄存器R7赋值100
D1:DJNZ R7,D1    	   ;--R7,结果不为0跳转到D1继续执行
   RET				   ;返回函数

DJNZ指令周期为两个机器周期,即执行DJNZ指令需要2μs,每执行一次寄存器R7减一,不断重复,直到R7为0后,指令结束。即D1语句执行次数为100次,延时100*2=200μs

2、多重循环较长延时

周期性点亮LED灯的延时函数:

​ 下面给出的是周期性点亮一个LED灯的延时函数,采用双重循环的方式来实现。

DELAY: MOV R7,#250 
D1: MOV R6,#250 
D2: DJNZ R6,D2 		;250*2=500μs
	 DJNZ R7,D1		 ;250*500μs=0.125S
	 RET
  • 第一句:DELAY: MOV R7,#250 ;执行了一次,没有任何语句跳转给它,单周期。
  • 第二句:D1: MOV R6,#250 ;执行了250次,全部是第四句跳过来的,单周期。250
  • 第三句:D2: DJNZ R6,D2 ;原地执行了250次,从第二句顺延(第二句执行完,没有其它跳转的话肯定要执行第三句)过来250次,也就是250x250=62500次,双周期*2。125000
  • 第四句: DJNZ R7,D1 ; 从第三句顺延过来250次,双周期*2。500
    总计:1+250+125000+500=125751次,乘以1微秒,换算约为0.125秒。

Q:若要使LED每隔1S亮灭进行周期性变化,上述双重循环还能否实现?程序如何修改?

A:51单片机每个寄存器最大存储256字节,因此两个寄存器循环并不能达到延时1S的效果。为此我们为其增加一层循环,以三层循环来实现更长时间的延时。

1|DELAY:MOV R5,#10
2|D1: MOV R6,#200
3|D2: MOV R7,#250
4|		DJNZ R7,$		;250*2=500μs
5|		DJNZ R6,D2		;500*200=100000μs
6|		DJNZ R5,D1		;100000*10=1000000μs
7|		RET

对每条指令进行计算得出延时时间约为1.1秒,近似等于1秒

NOP指令

NOP指令在汇编中的作用是空指令,意味着什么都不做,一般用来控制CPU时间,达到时钟延时的效果。

​ NOP指令为单周期指令,可由晶振频率计算出延时时间,对于12M晶振,延时1μs。

​ 仍以上述延时1S为例,可在程序式中加入NOP指令:

1|DELAY:MOV R5,#10
2|D1: MOV R6,#200
3|D2: MOV R7,#250
4|	NOP
5|		DJNZ R7,$		;250*2=500μs
6|		DJNZ R6,D2		;500*200=100000μs
7|		DJNZ R5,D1		;100000*10=1000000μs
8|		RET

二、汇编语言查表法求平方数

(一)汇编程序

要求:通过查表法,求出1~9的平方数

代码如下:

1|ORG 0000H		;定义下一条的指令放在地址为0000H存储器
2|LJMP A1		;长跳转指令至A1	
3|ORG 0080H		
4|A1: NOP	
5|	  NOP
6|	  MOV SP,#60H
7|	  MOV DPTR,#2000H
8|    MOV A,#03H
9|	  MOVC A,@A+DPTR
10|A2: SJMP A2
11|	   ORG 2000H
12|    DB 01h,04h,09h,10h,19h,24h,31h,40h,51h	
13|	END
  • 在程序存储器中0003H~0023H是中断入口,在编写程序时此空间需要预留出来。同时,LJMP是一个3字节指令,从复位入口0000H到第一个中断入口地址0003H刚好为3字节,刚好可以存放一个长跳转指令,且LJMP恰好可以跳转到64K程序空间的任一位置,因此主程序可以放到程序空间的任一位置。上述LJMP程序跳转到0080H开始执行其余有效代码。
  • **NOP:**在51单片机上电复位后,在刚开始执行代码含有多个空操作,目的使单片机外围扩展芯片从复位状态回到正常状态中
  • MOV SP,#60H :SP是栈指令,单片机上电后默认SP赋值为07H,意味着08H及往上均为堆栈区,而这在实际中是不合理的,因为08H占用了第一组工作寄存区以及往上的寄存区。因此在实际中,我们在RAM中的高端作为堆栈区,一般以60H~7FH作为堆栈区。
  • DB指令:声明并初始化数据。声明数据的本质就是:在内存中占用一块空间 ;初始化数据的本质就是:给这个空间赋予一个值 。举例:db 0,0,0,0,0,在内存中占用了5个字节的空间,这5个字节的值都是0 。
ORG 2000H  ;对表格头的
DB 01h,04h,09h,10h,19h,24h,31h,40h,51h

将表格中第一个数据填充到地址2000H中,以此类推,表格数据被存放到2000H~2008H中

  • MOV DPTR,#2000H ,MOVC A,@A+DPTR
    • 变址寻址——指令中使用DPTR的内容作为基地址,再与累加器A的内容相加,其合作为操作数地址,常用于查表操作。
    • 特点——DPTR应预先存放有操作数的基地址;累加器A中预告放有被寻址操作数地址与基地址之间的偏移量,该地址偏移量应该是00H~FFH范围内的无符号数;
    • 寻址空间——ROM,这是访问程序存储器ROM中数据的唯一方式。

代码优化:

上述采用固定表格位置的方法进行查表,若有效程序代码空间大于2000H,则会进入或覆盖表格空间,表格将会失效。为了解决该问题,我们设计浮动表格,使表格始终处于程序段有效代码的最后。

实现方法:先知道标号隐含着地址信息,因此可以将表格头所在的标号地址作为DPTR基地址。

7|	MOV DPTR,#tab  ;将标号的位置取出来赋值给DPTR
11|	;ORG 2000H	;不用ORG对表格位置进行声明
12|tab:DB 01h,04h,09h,10h,19h,24h,31h,40h,51h	;浮动表格,自动存放在程序段有效代码最后

(二)在Edsim中验证程序

将上述代码利用Edsim软件进行仿真测试,结果如下:

image-20240320214443626

(三)在Proteus中验证程序

1、在keil软件中生成在Proteus中可调试的.omf文件

image-20240321010444319

2、将.omf文件加载到AT89C52芯片中进行调试

image-20240321010856405

image-20240321011508865

以上,实验得以验证。

三、普中开发板应用实例

​ 在利用普中开发板做实例之前,我们首先需要了解关于普中开发板的相关知识,详细可以参考以下链接:https://blog.csdn.net/yu57955/article/details/120928956

STC-ISP软件是专门给STC系列单片机下载烧录程序的,并不能适用于ARM系列单片机,可以在http://www.stcmcu.com/官网下载最新的版本。详细使用指南参考:https://blog.csdn.net/qq_28576837/article/details/125712180

(一)周期性点亮LED灯

1、LED模块原理图

image-20240320231712351

上图左边8个口连接到单片机的P2.0口~P2.7口, 右边VCC是指电源;

VCC左边的蓝色方框是指电阻,右上角1K指1000Ω,用于保护电路,防止超载;

中间绿色的为LED二极管,当P2.0口为低电平时,则对应电路上的LED灯D1亮;若为高电平,则对应电路上的LED灯D1灭,其他灯同理。

2、代码实现

(1)C程序周期性点亮LED

  • 其中头文件 #include <REGX52.H>#include <REG52.H>区别在于第一个头文件中声明了I/O口的每个引脚如 P2_0,而第二个头文件只声明了 P2.

  • #include <REGX52.H>

image-20240320232722830

  • #include <REG52.H>

image-20240320232703106

  • 其中C程序的延时函数可以直接使用STC-ISP生成代码

image-20240320232954072

(2)汇编代码周期性点亮LED

image-20240321164641054

3、将Keil程序生成的.hex文件通过STC-ISP写入单片机中

image-20240320233437536

注意:烧录过程中,单片机需要在上电状态下点击下载/编程,再将单片机重启显示下载完成

image-20240320233631901

4、实验结果

(1)C程序结果

(2)汇编程序结果

(二)LED流水灯

1、C程序LED流水灯

在这里插入图片描述

2、汇编程序LED流水灯

image-20240321163059600

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值