单片机小小常识
扫描二维码
随时随地手机看文章
单片机能够执行的指令共有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-2C51存储类型与8051存储空间的对应关系
存储区
描述
data
片内RAM的低128字节,可在一个周期内直接寻址,访问速度快
bdata片内RAM的可位寻址区,16字节,允许位与字节混合访问
idata可间接寻址片内RAM的256字节
xdata可寻址指令由MOVX @DPTR访问的64kb片外RAM空间
pdata外部存储区的256个字节,可以分页的寻址由指令MOVX @DPTR
访问的64KB片外RAM空间
code程序存储区,使用DPTR寻址。
表2-3C51存储类型及其大小和值域
存储类型
长度/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~65535
xdata(寻址片外RAM)
16
2
0~65535
对地址单元的内容进行修改有三种方法在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 intuint;
void main()
{
uchar var1;
uintvar2;
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、pdat