单片机能够执行的指令共有111条,只需一个机器周期的指令有64条,两个机器周期的指令有45条,而4个机器周期的指令仅有两条(乘法和除法)。
指令的符号:/位操作的前缀,表示对该位取反。
直接寻址:指的是内部数据存储器中存放的数据的地址,或存放数据的一个特殊功能寄存器地址,eg MOV A, 30H。
寄存器寻址:寻址范围,4个工作寄存器组共32个通用寄存器(R0~R7),eg MOV A, R5。
寄存器间接寻址:寻址范围,内部低128字节单元(只能使用R0和R1做间接寄存器), eg MOV A, @R0。
基址加变址:MCS-51单片机的基址加变址只能对程序存储器进行寻址,eg MOVC A, @A+PC MOV A, @A+DPTR。
数据类型: unsigned char 类型可以表示的数值范围是0~255,signed char 的类型可表示的范围是-128~+127。
unsigned int 类型可以表示的数值范围是0~65535,signed int 的类型可表示的范围是-327678~+332767。
sfr特殊功能寄存器:是C51的扩充数据类型,sfr占有一个内存单元,0~255.sfr16占有两个内存单元,如T0和T1取值范围是0~65535。
8051的时钟有两种方式,一种是片内时钟振荡方式,但需在18和19脚外接石英晶体(2-12MHz)和振荡电容,振荡电容的值一般取10p-30p。另外一种是外部时钟方式,即将XTAL1接地,外部时钟信号从XTAL2脚输入。
单片机中MOVC A,@A+DPTR和MOVC A,@A+PC有何区别?
这两条指令的通常用于查表操作,功能完全一样,但使用起来却有一定的差别,现详细说明如下。
PC是程序指针,是十六位的,DPTR是一个16位的数据指针寄存器,按理,它们的寻址范围都应是64K。我们在学习特殊功能寄存器时已知道,程序计数器PC是始终跟踪着程序的执行的。也就是说,PC的值是随程序的执行情况自动改变的,我们不可以随便的给PC赋值。而DPTR是一个数据指针,我们就可以给空上数据指针DPTR进行赋值。
我们再看指令MOVC A,@A+PC这条指令的意思是将PC的值与累加器A的值相加作为一个地址,而PC是固定的,累加器A是一个8位的寄存器,它的寻址范围是256个地址单元。讲到这里,大家应可明白,MOVC A,@A+PC这条指令的寻址范围其实就是只能在当前指令下256个地址单元。所在,这在我们实际应用中,可能就会有一个问题,如果我们需要查询的数据表在256个地址单元之内,则可以用MOVC A,@A+PC这条指令进行查表操作,如果超过了256个单元,则不能用这条指令进行查表操作。刚才我们已说到,DPTR是一个数据指针,这个数据指针我们可以给它赋值操作的。通过赋值操作。我们可以使MOVC A,@A+DPTR这条指令的寻址范围达到64K。这就是这两条指令在实际应用当中要注意的问题。
ORG与CSEG AT伪指令的区别:
1.伪指令org用来规定目标程序存放单元的偏移量。
比如,如果在源程序的第一条指令前用了如下指令:
org 200h 那么,汇编程序会把指令指针的ip的值设成200h,即目标程序的第一个字节放在200h处,后面的 内容则顺序存放,除非遇上另一个org 语句。
2.CSEG AT 定义绝对地址,而不是相对地址,
CSEG [AT absolute address] Define an absolute segment within the code address space.
当有C51与汇编混合编程时而要定位某段汇编代码,最好使用CSEG AT XXXH。
eg
绝对地址和相对地址指的是同一个地址,他们的区别就是一个与你当前位置无关(绝对)一个有关(相对),相对地址的内容就是绝对地址去掉你当前的地址。还是那个例子,当前位置:/etc,目标文件夹绝对地址:/etc/init.d,相对地址:init.d。
追问
比如说金山词霸: F:\金山词霸\PowerWordDict 这个是绝对地址是吗 哪什么是它的相对地址呢
回答
如果在windows里面的话是的,它就是绝对地址。相对地址要有你目前的位置为前提,如果你在F:\,那么它的相对地址就是 金山词霸\PowerWordDict。
某一位与0异或保持原值,与一异或取反。
控制转移指令:
用于控制程序的流向,所控制的范围即为程序存储器区间,MCS-51系列单片机的控制转移指令相对丰富,有可对64kB程序空间地址单元进行访问的长调用、长转移指令,也有可对2kB字节进行访问的绝对调用和绝对转移指令,还有在一页范围内短相对转移及其它无条件转移指令,这些指令的执行一般都不会对标志位有影响。
[1]. 无条件转移指令(4条)
这组指令执行完后,程序就会无条件转移到指令所指向的地址上去。长转移指令访问的程序存储器空间为16地址64kB,绝对转移指令访问的程序存储器空间为11位地址2kB空间。
LJMP addr16 ;addr16→(PC),给程序计数器赋予新值(16位地址)
AJMP addr11 ;(PC)+2→(PC),addr11→(PC10-0)程序计数器赋予新值(11位地址),(PC15-11)不改变
SJMP rel ;(PC)+ 2 + rel→(PC)当前程序计数器先加上2再加上偏移量给程序计数器赋予新值
JMP @A+DPTR ;(A)+ (DPTR)→(PC),累加器所指向地址单元的值加上数据指针的值给程序计数器赋予新值
表2-2 C51存储类型与8051存储空间的对应关系
存储区 | 描述 |
data | 片内RAM的低128字节,可在一个周期内直接寻址,访问速度快 |
bdata | 片内RAM的可位寻址区,16字节,允许位与字节混合访问 |
idata | 可间接寻址片内RAM的256字节 |
xdata | 可寻址指令由MOVX @DPTR访问的64kb片外RAM空间 |
pdata | 外部存储区的256个字节,可以分页的寻址由指令MOVX @DPTR 访问的64KB片外RAM空间 |
code | 程序存储区,使用DPTR寻址。 |
表2-3 C51存储类型及其大小和值域
存储类型 | 长度/bit | 长度/byte | 值域 |
data(直接寻址片外RAM) | 8 | 1 | 0~255 |
idata(间接寻址片内RAM) | 8 | 1 | 0~255 |
pdata(分页寻址片外RAM) | 8 | 1 | 0~255 |
code(寻址ROM) | 16 | 2 | 0~65 535 |
xdata(寻址片外RAM) | 16 | 2 | 0~65 535 |
对地址单元的内容进行修改有三种方法在C51中,可以通过变量的形势访问51单片机的存储器,也可以通过绝对地址来访问存储器
三种方法如下:
一、绝对地址访问
使用C51运行库中预定义宏(就是调用#include"absacc.h")
C51编译器提供了一组宏定义来对51单片机的code、data、pdata和xdata空间进行绝对寻址!
规定只能以无符号数方式访问,定义了8个宏定义,其函数原型如下:
#define CBYTE((unsigned char volatile*)0x50000L) //CBYTE以字节形势对code区寻址
#define DBYTE((unsigned char volatile*)0x40000L) //data区
#define PBYTE((unsigned char volatile*)0x30000L) //pdata区
#define XBYTE((unsigned char volatile*)0x20000L) //xdata区
#define CWORD(unsigned int volatile*)0x50000L) //以字形式对code区寻址
#define DWORD(unsigned int volatile*)0x40000L)
#define PWORD(unsigned int volatile*)0x30000L)
#define XWORD(unsigned int volstile*)0x20000L)
eg:
#include"absacc.h"
#include"reg52.h"
typedef unsigned char uchar;
typedef unsigned int uint;
void main()
{
uchar var1;
uint var2;
var1=XBYTE[0x0005]; //XBYTE[0x0005]访问片外RAM的0005字节单元
var2=XWORD[0x0002]; //XWORD[0x0002]访问片外RAM的0002字单元
XWORD[0x000] = 0xAABB; //将0xAABB送人外部RAM的0000H~0001地址单元中去
XBYTE[0x0002] = 0xAA; //将0xAA送入外部RAM的地址中
.
.
.
while(1);
}
2、通过指针访问
采用指针的访问的方法,可以在C51程序中对任意指定的存储器单元进行访问。
typedef unsigned char uchar;
typedef unsigned int uint;
void func()
{
uchar data var1;
uchar pdata *dp1; //定义一个指向pdata区的指针dp1
uint xdata *dp2; //定义一个指向xdata区的指针dp2,为uint型
uchar data *dp3; //定义一个指向data区的指针dp3,为char型
dp1=0x30; //dp1指针赋值,指向pdata区的30H单元
dp2=0x1000; //dp2指针赋值(uint型),指向xdata区的1000H单元
*dp1=0xff; //将数据0xff送到片外RAM30H单元
*dp2=0x1234; //将数据0x1234(由于是uint型,你懂得~~~),送到片外RAM1000H单元
dp3=&var1; //dp3指针指向data区的var1变量
*dp3=0x20; //给变量var1赋值0x20
}
3、使用C51扩展关键字 _at_ (这个用的最多了)
一般格式:
[存储类型] 数据类型说明 变量名 _at_ 地址常量;
其中,存储类型为data、bdata、idata、pdata、xdata等C51能识别的数据类型,如果省略,则会按照存储模式规定的默认存储类型确定变量的存储区域;数据类型为C51支持的数据类型;地址常数用于指定变量的绝对地址,必须位于有效的存储器空间之内;使用_at_定义的变量必须为全局变量。
例如:
typedef unsigned char uchar;
typedef unsigned int uint;
data uchar x1 _at_ 0x40; //在data区中定义字节变量x1,地址为0x40H,这里是uchar
xdata uint x2 _at_ 0x2000; //在xdata区中定义字变量x2,它的地址为0x2000H,这里是uint
单片机的内部究竟有哪些部分组成的,它们都有些什么作用呢?让我们先来了解其中的ROM存储器:
一.半导体存储器ROM
1.几个基本概念
上一课我们讲到了把编译后的指令下载到单片机后这条指令一定在单片机内的某个地方,那么它究竟在哪里呢?原来它就放在一个叫程序存储器的地方,英文名称ROM(全称为Read Only Memory),叫只读存储器。它是一个什么东西呢?在讨论这个问题之前,让我们先来看几个物理现象:(1)数和物理现象的关系 不知大家是否还记得,在学习数字电路时我们曾用一盏灯的亮和灭来表示电平的高和低,即用“1”来表示高电平,用“0”来表示低电平,如果现在有两盏灯那它会有几种状态呢?
0 0 0 1 1 0 1 1 两盏灯的组合就是四种状态:00,01,10,11。如此看来灯的亮和灭这种物理现象同数字确实有着某种联系,如果我们把它们按一定的规律排列好,那么电平的高或低就可以用数字来表了,换句话说:不同的数字可以代表不同数量灯的电平高或低。比如:
0000,0001,0010,0011,0100,0101,0110,0111,1000,1001,1010,1011,1100,1101,1110,1111这十六种组合就可以代表四盏灯的状态,能理解吗?
(2)位及字节的含义
在单片机中,一盏灯(实际上是一根线)我们称它为一位,它有两种状态(“0”或“1”),分别应电平的高或低,它是单片机最基本的数量单位,用BIT来表示。8盏灯(八根线)有256种状态,这8盏灯(也就是8位)我们把它称为一个字节,用BYTE表示。至于为什么要怎么规定,这就不需要你我操心了,我们只要记住就可以了。那么单片机是如何来储存这些数字所代表的字节的状态的呢?接着往下看:
2.半导体存储器的工作原理
存储器就是用来存放数据的地方,它其实是利用电平的高或低来存放数据的,也就是说,它实际上存放的是电平的高或低的状态,而不是我们所习惯上认为的“1234”这样的数字。那它是如何工作的呢?一个存储器就象一个小抽屉,一个小抽屉里有8个小盒子每个小盒子用来存放1位“电荷”,电荷通过与它相连的电线传进来或释放掉,至于电荷在小盒子里是怎样存放的,这就不用我们操心了,您可以把电线想象成水管,小盒子里的电荷就象是水,那就好理解了存储器中的1个小抽屉我们把它称之为1个“单元”,相当于1个字节,而1个小盒子就相当于1位。
有了这么一个构造,我们就可以开始存放数据了,比如我们要放进一个数据“00011010”,我们只要把第2号、第4号和第5号小盒子里存满电荷,而其它小盒子里的电荷给放掉就行了。可是问题又出来了,一个存储器有好多相同的单元,线是并联着的(看D7-D0),在放入电荷的时候,会将电荷放入所有的字节单元中,而释放电荷的时候,会把每个单元中的电荷都放掉,这样的话,不管存储器有多少个字节单元,都只能放同一个数,这当然不是我们所希望的。
因此,我们要在结构上稍作变化,看上面的图,在每个单元上有根线与译码器相连,我想要把数据放进哪个单元,就通过译码器给哪个单元发一个信号,由译码器的通过这根线把相应的开关打开,这样电荷就可以自由地进出了。那么这样是不是就能随意地向存储器写入或者读出数据了呢?其实还不能,当我们向存储器写入数据时,必须先把这个开关切换到写入端;而要读出数据时,就得先把开关切换到读出端;而片选端则是为了区分不同的存储器设置的。
3.半导体存储器的译码
简单介绍一下:我们知道,1根线可以代表2种状态;2根线可以代表4种状态;3根线可以代表8种;256种状态又需要几根线代表?8根线,所以一片6264存储器我们只需要16根线就可以了。
4.存储器的选片及总线的概念 至此,译码的问题解决了,让我们再来关注另外一个问题:送入每个字节的8根线又是从什么地方来的呢?它就是从单片机的外部引脚上接过来的,一般这8根线除了接一个存储器之外,还要接其它的器件,这样问题又出来了,这8根线既然不是存储器和单片机之间专用的,如果总是将某个单元接在这8根线上,就不行了,比如这个存储器单元中的数值是“FFH”,另一个存储器的单元是“00H”,那么这根线到底是处于高电平,还是低电平?岂不是要打架看谁历害了?所以我们必须让它们分离。
办法当然也简单,当外面的线接到集成电路的引脚上来后,不直接接到各单元去,中间再加一组开关就行了。这组开关就是前面提到的控制器(看前面的图),平时我们让开关打开着,如果确实是要向这个存储器中写入数据,或要从存储器中读出数据,再让开关切换到相应的位置就行了。这组开关由三根引线选择读控制端、写控制端和片选端,要将数据写入,先由控制器选中该片,然后发出相应的写信号,开关切换到相应的位置,并将传过来的数据(电荷)写入片中;如果要读信号,先选中该片,然后发出读信号,开关也切换到相应的位置上,数据就被送出去了;另外读和写信号还同时受到译码器的控制,由于选端的不同,所以虽有读或写信号,但没有片选信号,所以另一个存储器就不会“误会”而开门,造成冲突,那么会不会同时选中两个存储器呢?只要是设计好的系统就不会,因为它是由计算机来控制的,如果真的出现同时选中两个存储器的话,那就是电路出故障了。
如此看来,存储器要想写入或者读出数据还真是不简单,不过好在这些都是由计算机自动完成的,不需要我们去操心。从上面的介绍中我们已经看到,用来传递数据的8根线(51单片机是8根)并不是专用的,而是很多器件大家共用的,所以我们把它们称之为数据总线(总线英文名为BUS),即公交道,谁都可以走;而16根地址线(51单片机共有16根地址线,这些以后会讲解,这里不必死记硬背)也是连在一起的,我们把它们称之为地址总线,
5.半导体存储器的分类
第一课中我们提到过,89C51是一种带Flash ROM的单片机,什么是Flash ROM?它到底是一种什么东西呢?ROM我们已经知道,是只读存储器,所谓只读,从字面上理解那就是只可以从里面读出数据,而不能写进去,它类似于我们的书本,发到我们手里之后,我们只能读里面的内容,不可以随意更改书本上的内容。ROM就是单片机中用来存放程序的地方,前面我们下载到单片机的指令就放在这个地方。讲到这里大家也许会感到困惑,既然ROM是只读存储器,那么指令又是如何进入其中的呢?其实所谓的只读只是针对正常工作情况下而言,也就是在使用这块存储器的时候,而不是指制造这块芯片的时候,只要让存储器满足一定的条件就能把数据预先写进去,这个道理也很好理解,书本拿到我们手里是不能改了,但当它还是原材料--白纸的时候,我们完全可以由印刷厂把内容印上去嘛。前面的编程就是这么回事!
Flash ROM是一种快速存储式只读存储器,这种程序存储器的特点就是既可以电擦写,而且掉电后程序还能保存,编程寿命可以达到几千至几万次,所以我们的实验系统是可以反复烧写的,您尽管使用。目前新型的单片机都采用这种程序存储器;当然,除了这种程序存储器外,还有两种早期的程序存储器产品,简单介绍一下:PROM EPROM和EEPROM,PROM称之为可编程只读存储器,就象我们的练习本,买来的时候是空白的,可以写东西上去,可一旦写上去,就擦不掉了,所以它只能写一次,要是写错了,就报废了,习惯上我们把带这种程序存储器的单片机称为OTP型单片机,如果您的产品批量生产,又要求价格比较低的话,带这种程序存储器的单片机是非常合适的;
EPROM,称之为紫外线擦除的可编程只读存储器,它里面的内容写上去之后,如果觉得不满意,可以用一种特殊的方法去掉后重写,就是用紫外线照射,紫外线就象“消字灵”,可以把字去掉,然后再重写,当然消的次数多了,也就不灵光了,所以这种芯片可以擦除的次数也是有限的——几百次吧,电脑上的BIOS芯片采用的就是这种结构的存储器;EEPROM,前一种存储器的擦写要用紫外线,而这种存储器可以直接用电擦写,比较方便数据的改写,它有点类似于FLASH存储器,但比FLASH存储器速度要慢,现在新型的外部扩展存储器都是都是这种结构。
了解了ROM,让我们再来简单讲讲另一种存储器,叫随机存取存储器,也叫内存,英文缩写为RAM(Random Access Memory),它是一种既可以随时改写,也可以随时读出里面数据的存储器,类似于我们上课用的黑板,可以随时写东西上去,也可以用黑板擦随时擦掉重写,它也是单片机中重要的组成部分,单片机中有很多的功能寄存器都与它有关。
二.本课总结
本课主要讲述了单片机的两种半导体存储器—只读存储器ROM和随机存储器RAM的工作原理,它们是单片机的重要组成部分,了解它的内部结构对我们学习单片机是很有帮助的。不过如果您一时对本课的内容还无法搞得很明白,也没有关系,随着学习的深入,我们还会慢慢地讲解相应的基础知识,可千万不要放弃哟?我在没有学会单片机之前也是如此囫囵吞枣的
上一篇:单片机I2C驱动程序
下一篇:单总线驱动程序(DS18B20)
推荐阅读最新更新时间:2024-03-16 15:28