单片机ofeh_单片机学习之六:基本I/O口试验二:跑马灯

本文介绍了单片机中如何使用左移指令RL实现跑马灯效果,通过掌握寄存器A、Rn的使用,结合延时程序,简化程序设计。讲解了RL指令的作用,累加器A在单片机中的重要性,并提供了延时子程序的详细分析。同时,探讨了单片机中工作寄存器区的选择及其默认设置,以及课后练习设计了一个延迟1s的跑马灯程序。
摘要由CSDN通过智能技术生成

一、试验现象:

二极管从右至左依次发光。

二、试验目的:

l         掌握寄存器A,Rn的使用方法

l         掌握左移指令

l         掌握延时程序的编写

三、任务分析:

电路图同试验1,有了上一个试验的基础,这个程序对我们就没有什么难度啦。我们可以这样作:

首先:mov p0,#ofeh(让最右边的灯亮),然后经过一段延时,再:mov p1,#ofdh,这样依次赋值,直到:mov p0,#07fh(最左面的灯亮)。然后用ajmp指令返回,让灯光再重新开始循环。

这样固然可以,但是程序不够简单明了,我们要写8个mov语句。设想一下,假如有几十个灯,那写起来不是麻烦死啦?

好在单片机有一条左移指令rl a,它的作用是把累加器a中的数循环左移。

顺便说一下累加器a,它是单片机中的最常用的寄存器,大部分单操作数的指令都以a作为操作对象(例如rl a);也有很多双操作数指令的一个操作数取自a(例如mov a,#00h);还有加、减、乘、除等算数指令的运算结果也经常保留在a中,或者ab寄存器对中。

所以我们的程序就可以这样来实现啦:首先给a赋值,再输出到p0;然后延时;接下来把a中的数进行左移。然后重复上面的过程就可以啦。

四、试验程序

org  0000h

start:  clr p1.5

mov a,#0feh        ;给a赋立即数,执行之后,a中的数据是11111110

loop:  mov p0,a          ;把a中的数据传输到p0

lcall delay         ;(1)

rl a               ;(2)

ajmp loop          ;返回标号为loop的指令

delay: mov r6,#02h        ;(3)

del1:  mov r5,#0ffh       ;(4)

del2:  djnz r5,del2        ;(5)

djnz r6,del1        ;(6)

ret               ;(7)

end

注释:

1、这是一个子程序调用指令。在程序设计中,常常把具有一定功能的公用程序编成子程序,以便让主程序调用。

该指令的执行过程是这样的:当执行lcall指令后,程序就转到lcall后面标号delay指定的程序处往下执行,当执行遇到ret指令时,就返回lcall指令下面的一条指令,即rl a指令。

从上面的分析,我们可以知道:标号为delay的程序应该是一段延时程序,那么它到底延时了多长时间呢?我们一会给大家讲解这个时间的计算方法,先往下看吧。

同样,子程序调用也有两条指令:acall和lcall。两者的区别是:acall指令调用的子程序起始地址必须和acall后面的第一条指令在同一个2k区域的程序存储器内;而lcall指令可以调用存放在程序存储器中64K字节范围内的任何地方的子程序。简单的说就是acall调用的范围小,而lcall的范围大。如果你拿不准的话,就用lcall吧。

2、这条指令的功能是:把累加器a中的内容向左移动一位,最高位的内容A7被移动到最低位A0,图示如下:

3、现在我们来分析delay子程序的延时时间:

我们先看(3)(4)(5)(6)(7)这样几个语句:

(3)的意思是给r6赋值02h。r6是什么?我们好像以前没有说过。大家先知道它也是一个8位的寄存器就行啦,关于它的内容,我们下面在介绍。

(4)的意思和(3)类似,不再赘述。

(5)应用了djnz指令,这个指令的意思是:减1不为0转移。因此语句(6)的意思是:把r5中间存的内容减去1,如果不是0,就继续执行该条语句,否则,执行下面的语句。

(6)根据上面的分析我们知道:(6)的意思是:把r6中的内容减1,如果不是0,就返回标号为del1的程序,重新给r5赋值0ffh,然后在对r5进行减1运算。

从分析可见,如果延时程序执行完,djnz指令总的执行次数是:02h×0ffh,即2×255=510次。

可见,如果我们知道执行一次djnz指令的时间,我们就可以算出这个程序的延时时间了。那么执行一次djnz指令需要多少时间呢?

单片机的指令执行起来所花费的时间是不一样的,有的指令执行时间短,只需要1个机器周期,而有的指令执行时间长,需要4个机器周期。Djnz指令的执行时间是2个机器周期。

每一个机器周期又是多长呢?从相关教材上,我们知道1个机器周期是振荡周期的12倍。

而振荡周期T=1/振荡频率=1/12MHZ

所以延时程序的总的延时时间是:2×255×2×12×(1/12MHZ)=1ms

好啦,现在把上面的程序下载到单片机中,你看到了什么?

怎么回事,所有的灯都亮啦!

当然啦,因为我们的延时太短啦,只有1ms,所以我们的眼睛根本分辨不出来。我们现在把延时增加为100ms,程序修改如下:

org  0000h

start:  clr p1.5

mov a,#0feh

loop:  mov p0,a

lcall delay

rl a

ajmp loop

delay: mov r7,#100    ;把1ms延时子程序执行100次

del1:  mov r6,#02h

del2:  mov r5,#0ffh

del3:  djnz r5,del3

djnz r6,del2

djnz r7,del1

ret

end

现在再看看,一切正常啦,ok!

4、现在来看看寄存器R的问题

单片机的存储器结构和常见的微型计算机的配置方式不同,把程序存储器和数据存储器分开。程序存储器用来存放程序,数据存储器用来存放程序运行需要的常数和变量。

单片机的数据存储器分为内部存储器和外部存储器,用mov访问内部数据存储器,用movx访问外部数据存储器。

内部数据存储器是最灵活的地址空间,一共有256字节。这256个字节被分为两组:00h~7fh的低128字节是内部RAM区;80h~ffh的高128字节为特殊功能寄存器区。其中低128字节的地址分配如下图所示:

从图上可见,低128字节中,从00h~1fh共32个字节是四个通用的工作寄存器区,每一个区有8个工作寄存器,编号均为从R0~R7。

大家可能会问,既然四个工作寄存器组的名字都叫R0~R7,那么,上面的程序中间用的寄存器到底是哪个呢?

当前程序使用的工作寄存器区是有程序状态字PSW决定的。

那么PSW又在哪里呢?

刚才我们说到80h~ffh的高128字节是特殊功能寄存器区,PSW就在这个区里面。这个区域还有很多别的特殊功能寄存器,大家可以参考相关资料。

PSW是一个8位的寄存器,它各位的说明如下:

其中,决定选择哪个寄存器区的是RS1和RS0这两位,为00时,选择0区;01时选择1区;10时选择2区;11时选择3区。

大家可能会问,程序中间并没有给这个寄存器赋值,那么它到底选择哪个区域呢?

由于单片机被复位后,所有的寄存器请零,所以在本程序中,缺省的使用的是0区的寄存器组。

5、课后练习

(1)、学习该试验中出现的理论知识,包括程序存储器,数据存储器的地址分配,和相关指令。

(2)、编写一个跑马灯程序,让二极管从左至右发光,延迟时间是1s,即1000ms。注意,可不是把上面程序中的mov r7,#100,改成mov r7,#1000,那么简单哦。

本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值