本节书摘来自异步社区《例说8051:单片机程序设计案例教程》一书中的第2章,第2-1节,作者 张义和,陈敌北,更多章节内容可以访问云栖社区“异步社区”公众号查看。
第 2 章 输出口的应用
本章内容丰富,主要包括3部分:
2-1 认识MCS-51的存储器结构
除了无ROM型的8031及8032外,MCS-51的存储器包括程序存储器(ROM)与数据存储器(RAM)两部分,一般这两部分是独立的个体。标准的8x51系列具有4KB程序存储器、128B数据存储器,而标准的8x52系列具有8KB、256B数据存储器,刚好是8x51系列的两倍。不管是8x51、8031、8032还是8x52,其外部扩展的程序存储器或数据存储器最多为64KB,如表2-1所示。
近年来许多半导体厂商所推出的MCS-51兼容单片机都增大其内部程序存储器与数据存储器,例如Atmel半导体公司的TS83C51RB2,其内部有16KB程序存储器、256B数据存储器;TS83C51RC2,其内部有32KB程序存储器、256B数据存储器;TS83C51RD2,其内部有64KB程序存储器、768B数据存储器。
2-1-1 程序存储器
顾名思义,程序存储器(ROM)是存放程序的存储器,而CPU将自动从程序存储器读取所要执行的指令。MCS-51的程序存储器结构如图2-1所示,可选择使用内部程序存储器或外部程序存储器,说明如下:
若使用8031或8032,由于内部没有程序存储器,一定要使用外部程序存储器,所以其引脚必须接地。
当引脚接高电平时,CPU将使用内部程序存储器,若程序超过4KB(8x51)或8KB(8x52),则CPU会自动从外部程序存储器里,读取超过部分的程序代码。
当引脚接地时,CPU将从外部程序存储器读取所要执行的指令,而CPU内部的程序存储器形同虚设。
注意:4KB的程序存储器对于初学者而言,已是绰绰有余。另外,坏掉的8x51/8x52,很可能是其中的程序存储器坏掉,这时可将其引脚接地,改为外接程序存储器,即可当作8031/8032使用。
当CPU复位后,程序将从程序存储器0000H位置开始执行,如果没有遇到跳转指令,则按程序存储器顺序执行。当然,程序存储器前面几个位置还有一些特殊功能,留到第5章介绍中断时,再详细说明。
2-1-2 数据存储器
MCS-51的程序存储器与数据存储器是分开的独立区域,所以访问数据存储器时,所使用的地址并不会与程序存储器冲突。相对于程序存储器,数据存储器就比较不简单,如图2-2所示。
如图2-2所示,8051的数据存储器中,除内部数据存储器外,还可扩展外部数据存储器,这两部分的数据存储器可以并存。不过,访问数据存储器时,所采用的指令并不一样,例如访问内部数据存储器时,可用MOV指令,但访问外部数据存储器时,则使用MOVX指令。
另外,内部数据存储器也有些复杂,如图2-3所示,说明如下:
从0000H到007FH之间的128B为可直接寻址或间接寻址的存储器,至于“直接寻址”与“间接寻址”,将在2-5节再详细说明。在这一区域里的数据存储器又可分成三部分,说明如下。
● 寄存器组区
0000H到001FH的32个地址为寄存器组(Register Bank)区:0000H到0007H为寄存器组0(即RB0),0008H到000FH为寄存器组1(即RB1),0010H到0017H为寄存器组2(即RB2),0018H到001FH为寄存器组3(即RB3)。每组寄存器组都包含R0~R7共8个寄存器,而在任何一个时刻,只能使用其中一组寄存器组。
对于寄存器组的切换可以由程序状态字寄存器(Program Status Word,PSW)中的RS1与RS0来决定,如表2-2所示。
当CPU复位时,系统的堆栈指针(SP)指向07H地址,所以数据存入堆栈时,将从08H开始,也就是RB1里的R0地址。为避免冲突或不必要的错误,通常会把堆栈指针移到30H以后的地址。
● 可位寻址区
0020H到002FH共16个字节的存储器区为可位寻址区,通常访问存储器是以一个字节(B)为单位,所谓“可位寻址”是指可以指定访问一个位(bit),在8051里,只要使用布尔运算指令,即可进行位操作,例如,要把20H存储器地址的bit 5设置为1,则可使用下列指令:
SETB 20H.5
另外,从0020H到002FH的16个字节总共128个位(168),也可以直接指定为0到127,以刚才的20H存储器地址的bit 5来说,可指定为5,即
SETB 05
同理,若要将25H存储器地址的bit 2清除为0,则可使用下列指令:
CLR 25H.2
或(5'8+2=42)
CLR 42
● 一般数据与堆栈区
0030H到007FH的80个字节地址为一般数据访问及堆栈区。由于CPU复位后,堆栈指针指向07H位置,为了确保数据的安全与程序执行的正确,如果在程序之中使用了PUSH、POP命令,最好能把堆栈指针改至本区,例如,要将堆栈指针移至0030H地址,则在程序开始处即使用如下命令:
MOV SP, #30H
从0080H到00FFH之间的128B为特殊功能寄存器(Special Function Register,SFR)或可直接寻址的存储器。特殊功能寄存器稍后再详细说明。
如果是8052/8032,则0080H到00FFH之间的128B,除了是特殊功能寄存器或可直接寻址的存储器外,另外也可以采用间接寻址的方式访问与这些特殊功能寄存器位置重叠但独立的存储器。
2-1-3 特殊功能寄存器
在MCS-51里,寄存器只是CPU里特定地址的数据存储器而已。而在0080H到00FFH之间的128B正是特殊功能寄存器所在的位置,什么是特殊功能寄存器呢?首先看看这128个地址,如图2-4所示。
图2-4 特殊功能寄存器
注意:上图中斜体字部分为8052/8032才有的寄存器,最左列的部分为可位寻址的寄存器,灰底的部分为89S51/52才有的。另外,8051/52、89C51/52只有一个数据指针寄存器,所以其中的DP0L应改为DPL,DP0H应改为DPH。
P0、P1、P2、P3
P0~P3为MCS-51的4个输入/输出口,其地址分别为80H、90H、0A0H及0B0H,稍后再详细介绍这4个输入/输出口。对于89S51而言,在执行烧录程序(In-System Programmable,ISP)时,P1.5引脚即为MOSI引脚,P1.6引脚即为MISO引脚,P1.7引脚即为SCK引脚。
SP
SP为堆栈指针寄存器(Stack Pointer register),其地址为81H。堆栈是一种特殊的数据存储方式,其数据的操作顺序是先进后出(First In Last Out,FILO),当数据以PUSH指令存入堆栈时,SP自动加1;以POP指令从堆栈取出数据时,SP自动减1。
DPL、DPH
89C51只有一个16位的数据指针寄存器(Data Pointer register,DPTR),而这个数据指针寄存器是由DPL与DPH两个8位的数据指针寄存器组成,其地址分别为82H、83H。若以DPL为低8位、DPH为高8位,所组成的16位数据指针寄存器将可寻址到64KB的数据地址。89S51有两个16位数据指针寄存器,分别是DP0L、DP0H、DP1L及DP1H,其地址分别为82H、83H、84H、85H。
PCON
PCON为电源控制寄存器(Power Control register),其地址为87H,其功能是设置CPU的电源方式,等讲到电源部分章节,再作说明。
TCON
TCON为定时器/计数器控制寄存器(Timer/Counter Control register),其地址为88H,其功能是设置定时器/计数器的启动、记录定时器/计数器溢出,以及设置外部中断的触发方式等,在第6章讲述定时器/计数器部分时再详细说明。
TMOD
TMOD为定时器/计数器方式控制寄存器(Timer/Counter Mode Control register),其地址为089H,其功能是设置定时器/计数器的方式,在第6章讲述定时器/计数器部分时再详细说明。
TL0、TL1、TH0、TH1
TL0、TH0为第一个定时器/计数器(Timer 0)的计数寄存器,其地址为8AH、8CH,将TH0与TL0组合即可实现16位的定时/计数功能。TL1、TH1为第二个定时器/计数器(Timer 1)的计数寄存器,其地址为8BH、8DH,将TH1与TL1组合即可实现16位的定时/计数功能,在第6章讲述定时器/计数器部分时再详细说明。
SCON
SCON为串行口控制寄存器(Serial Port Control register),其地址为98H,其功能是设置串行口工作方式与标志,在第7章关于串行口部分再详细说明。
SBUF
SBUF为串行口缓冲器,其地址为99H,这是由使用同一个地址的两个寄存器构成的,其中一个寄存器作为发送数据用的缓冲器,另一个寄存器作为接收数据用的缓冲器。至于如何分辨同一个地址的两个寄存器,则视指令而定,若是发送数据的指令,则自动定位到发送数据用的缓冲器;若是接收数据的指令,则自动定位到接收数据用的缓冲器,在第7章讲述串行口部分再进行详细说明。
IE
IE为中断使能寄存器(Interrupt Enable register),其地址为0A8H,其功能是启用中断功能,在第5章讲述中断部分再进行详细说明。
IP
IP为中断优先级寄存器(Interrupt Priority register),其地址为0B8H,其功能是设置中断的优先级,在第5章关于中断部分再进行详细说明。
T2CON
T2CON为Timer 2的定时器/计数器控制寄存器,其地址为0C8H,其功能是设置Timer 2的启动、记录定时/计数溢出,以及外部中断的触发方式等,而Timer 2只有在8052/8032中才有。
RCAP2L、RCAP2H
RCAP2L、RCAP2H为捕获寄存器(Capture register),其地址为0CAH、0CBH。当Timer 2在捕获方式时,若T2EX(P1.1)引脚上的输入信号由高电平转为低电平,TL2与TH2的内容将被载入到RCAP2L与RCAP2H里,就像是捕获Timer 2的内容到RCAP寄存器一样,而Timer 2只有在8052/8032中才有。
TL2、TH2
TL2、TH2为第三个定时器/计数器(Timer 2)的计数寄存器,其地址为0CCH、0CDH,将TH2与TL2组合即可执行16位的定时/计数,而Timer 2只有在8052/8032中才有。
PSW
PSW为CPU的程序状态字寄存器(Program Status Word register),其地址为0D0H,其内容说明如下:
● PSW.7:该位为进位位(CY),进行加法(减法)运算时,若最左边位(MSB,即bit 7)产生进位(借位)时,则此位将自动设置为1,即CY=1;否则CY=0。
● PSW.6:该位为辅助进位位(AC),进行加法(减法)运算时,若bit 3产生进位(借位)时,则此位将自动设置为1,即AC=1;否则AC=0。
● PSW.5:该位为用户标志位(F0),可由用户自行设置的位。
● PSW.4与PSW.3:这两个位为寄存器组选择位(RS1、RS0),其功能如表2-3所示。
● PSW.2:该位为溢位标志位(OV),当进行算术运算时,若发生溢位,则OV=1;否则OV=0。
● PSW.1:该位为保留位,没有提供服务。
● PSW.0:该位为奇偶位(P),8051采用偶校验,若ACC里有奇数个1,则P=1;若ACC里有偶数个1,则P=0。
ACC
ACC累加器(Accumulator)又称为A寄存器,其地址为0E0H,这个寄存器作为CPU主要运行的寄存器,可说是最常用的寄存器。
B
B寄存器的地址为0F0H,主要功能是配合A寄存器进行乘法或除法运算,进行乘法运算时,乘数放在B寄存器,而运算结果的高八位放在B寄存器;进行除法运算时,除数放在B寄存器,而运算的结果,即余数,放在B寄存器。若不进行乘/除法运算,B寄存器也可当成一般寄存器使用。
AUXR
AUXR寄存器为89S51新增的辅助寄存器(Auxiliary register),其地址为8EH,其内容说明如下:
● WDIDLE:该位设置在待机方式(Idle Mode)下,用于设置是否启用看门狗。若此位设置为1,则在Idle方式下将启用看门狗;若此位设置为0,则在Idle方式下将停用看门狗。
● DISRTO:该位用于设置是否输出复位信号。若此位设置为1,则Reset引脚(第9脚)只有输入功能;若此位设置为0,则在WDT计数完毕后,Reset引脚输出复位信号(即高电平脉冲)。
● DISALE:该位用于设置是否启用ALE信号。若此位设置为1,则只有在执行MOVX指令或MOVC指令时, ALE引脚(第30脚)才会正常工作;若此位设置为0,则固定每6个脉冲就输出1个高电平脉冲,详见第3章。
其他位为保留位。当然,这个寄存器只有在89S51里才有作用。
AUXR1
AUXR1寄存器为89S51新增的第二个辅助寄存器,其地址为0A2H,其内容说明如下:
● DPS:该位的功能是选择数据指针寄存器。若此位设置为1,则使用DP1L及DP1H。若此位设置为0,则使用DP0L及DP0H。
其他位为保留位。同样地,这个寄存器只有在89S51里才有作用。
WDTRST
WDTRST寄存器为89S51新增的看门狗定时器复位寄存器(Watchdog Timer Reset register),其地址为0A6H。当我们要启用WDT时,则按顺序将01EH、0EH写入WDTRST寄存器,当14位计数器溢位(达到16383,即3FFFH),即由RESET引脚送出一个高电平脉冲以达到复位状态。此脉冲的宽度为98TOSC,其中TOSC=1/FOSC,以12MHz的时钟脉冲为例,脉冲的宽度为,关于看门狗与节电方式,详见第4章。