原创 51手记之寄存器&寻址篇

2008-6-2 10:40 7627 12 12 分类: MCU/ 嵌入式

51手记之寄存器&寻址篇<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


题记:刚开始练51时就用C语言,现在想再加强一下汇编,所以不得不对单片机的硬件结构,特别是地址空间的分配方面详细的做一下了解了。于是决定拿起课本北航的《智能化测量控制仪表原理与设计》重新学一遍。书本是基础,然后应该把自己的一些应用体会实例什么的也加上去,这样学起来就事半功倍了毕竟这是再学习不是入门了。


 


51单片机的存储器结构:


 


    在物理上可以分为4个存储器空间:即片内ROM,片外ROM,片内RAM,片外RAM51/52单片机有64KB216次方,16条地址线寻址)的ROM地址空间。其中514KB的片内ROM528KB的片内ROM。至于使用片内还是片外的存储器,可以靠控制信号EA脚来设置,当从片内存储器开始取指令时,EA脚接正(对于ROM型单片机,通常采取此方式),此时如果指令地址超过4KB空间,则自动从片外开始取指令。而如果不使用片内存储器只从片外存储器取指令时,将EA接地即可。


 


ROM中有些单元是保留给系统使用的:0000-0002H单元是所有执行程序的入口地址,复位后程序总是从0000H单元开始执行。(所以在汇编的开始总是一句


ORG    0000


LJMP   nnnn       ;主程序中断入口


这个语句的意思是在0000这个地址上存放着LJMP nnnn这个语句,这里的nnnn是程序的入口地址,也就是编程者希望上电后程序从哪个地方开始执行)。


0003-002AH单元均匀的分为5段,用于5个中断服务程序的入口。(例如


    ORG   00BH


    LJMP  BT0         TO中断入口


也就是说00BH上存放着LJMP BTO这个语句,当产生TO中断时,前提当然是此中断处于开启状态了,程序将执行该语句,然后跳转到BT0所指的地址上的程序继续执行)。


5de94825-3a74-4a69-a589-63e1eb236dbe.jpg


 


 

51/52的片内数据存储器RAM256Byte,其中00H-7FH地址空间是直接寻址区。该区从00H-1FH是工作寄存器区,有4组工作寄存器组,至于使用哪一组则有PSWRS0RS1的状态决定。片内RAM20H-2FH地址为位寻址区。片内RAM80H-FFH地址空间是特殊功能寄存器(SFR)区。52系列有26个特殊功能寄存器。下面就把头文件reg52.h里的部分内容贴出来。(对于寄存器地址参考头文件就足够了,对于别的一些CPU也差不多)。


/*-------------------------------------------------------------------


REG52.H


 


Header file for generic 80C52 and 80C32 microcontroller.


Copyright (c) 1988-2001 Keil Elektronik GmbH and Keil Software, Inc.


All rights reserved.


-------------------------------------------------------------------*/


 


/*  BYTE Registers  */


sfr P0    = 0x80;


sfr P1    = 0x90;


sfr P2    = 0xA0;


sfr P3    = 0xB0;


sfr PSW   = 0xD0;


sfr ACC   = 0xE0;


sfr B     = 0xF0;


sfr SP    = 0x81;


sfr DPL   = 0x82;


sfr DPH   = 0x83;


sfr PCON  = 0x87;


sfr TCON  = 0x88;


sfr TMOD  = 0x89;


sfr TL0   = 0x8A;


sfr TL1   = 0x8B;


sfr TH0   = 0x8C;


sfr TH1   = 0x8D;


sfr IE    = 0xA8;


sfr IP    = 0xB8;


sfr SCON  = 0x98;


sfr SBUF  = 0x99;


 


/*  8052 Extensions  */


sfr T2CON  = 0xC8;


sfr RCAP2L = 0xCA;


sfr RCAP2H = 0xCB;


sfr TL2    = 0xCC;


sfr TH2    = 0xCD;


 


关于MCU的时钟问题:


 


    一般用的是12MHz的晶体,而MCU执行一个机器周期需要12各时钟周期(所谓时钟周期,就是指晶体振荡一个周期的时间),那么正好是1us,一般的指令需要1-2个机器周期即可完成,乘除指令的运算量比较大需要4各机器周期。


 


寻址方式:


    51单片机有7种寻址方式。


1、寄存器寻址:前面提到了内部RAM中的00H-1FH地址单元作为工作寄存器使用。一共是有32各地址单元,分成四组,每组有8个寄存器,命名为R0-R7,每次可以使用其中的一组。当使用R0-R7来表示操作数时,就属于寄存器寻址方式。


例如:MOV  A,R0;把寄存器R0的内容送入累加器A


2、直接寻址:在指令中直接给出操作数地址,就属于直接寻址方式。此时指令的操作数部分直接是操作数的地址。


例如:MOV A,2AH ;把RAM地址2AH的内容送入累加器A


3、立即寻址:


例如:MOV A,#3AH ;该指令就是表示把立即数3AH送入累加器A中,立即数前加上一个#,和直接寻址方式区分


4、寄存器间接寻址:若以寄存器的名称直接给出操作数的地址,则称为寄存器间接寻址。


例如:MOV A,@R0 ;该指令是把RO里的内容作为地址,这个地址的数据送入累加器A,注意前面需要加@


5、变址寻址:变址寻址是以某个寄存器的内容为基本的地址,然后在这个基址上加以地址的偏移量,才是真正的操作数地址。


例如:MOV A,@A+DPTR ;地址是A+DPTR的值,这个地址的内容送如累加器A


6、相对寻址:相对转移指令需要用到相对寻址方式,此时操作数部分给出的是地址的相对偏移量部分。


目的地址 = 源地址 + 指令字节数 + relrel可正可负)


例如:SJMP rel


7、位寻址:概念就不做解释了。还是把reg52.h这个头文件贴出来说。


/*  BIT Registers  */


/*  PSW  */


sbit CY    = PSW^7;


sbit AC    = PSW^6;


sbit F0    = PSW^5;


sbit RS1   = PSW^4;


sbit RS0   = PSW^3;


sbit OV    = PSW^2;


sbit P     = PSW^0; //8052 only


 


/*  TCON  */


sbit TF1   = TCON^7;


sbit TR1   = TCON^6;


sbit TF0   = TCON^5;


sbit TR0   = TCON^4;


sbit IE1   = TCON^3;


sbit IT1   = TCON^2;


sbit IE0   = TCON^1;


sbit IT0   = TCON^0;


 


/*  IE  */


sbit EA    = IE^7;


sbit ET2   = IE^5; //8052 only


sbit ES    = IE^4;


sbit ET1   = IE^3;


sbit EX1   = IE^2;


sbit ET0   = IE^1;


sbit EX0   = IE^0;


 


/*  IP  */


sbit PT2   = IP^5;


sbit PS    = IP^4;


sbit PT1   = IP^3;


sbit PX1   = IP^2;


sbit PT0   = IP^1;


sbit PX0   = IP^0;


 


/*  P3  */


sbit RD    = P3^7;


sbit WR    = P3^6;


sbit T1    = P3^5;


sbit T0    = P3^4;


sbit INT1  = P3^3;


sbit INT0  = P3^2;


sbit TXD   = P3^1;


sbit RXD   = P3^0;


 


/*  SCON  */


sbit SM0   = SCON^7;


sbit SM1   = SCON^6;


sbit SM2   = SCON^5;


sbit REN   = SCON^4;


sbit TB8   = SCON^3;


sbit RB8   = SCON^2;


sbit TI    = SCON^1;


sbit RI    = SCON^0;


 


/*  P1  */


sbit T2EX  = P1^1; // 8052 only


sbit T2    = P1^0; // 8052 only


             


/*  T2CON  */


sbit TF2    = T2CON^7;


sbit EXF2   = T2CON^6;


sbit RCLK   = T2CON^5;


sbit TCLK   = T2CON^4;


sbit EXEN2  = T2CON^3;


sbit TR2    = T2CON^2;


sbit C_T2   = T2CON^1;


sbit CP_RL2 = T2CON^0;


 


从前面的特殊功能寄存器地址里已经了解了它们在RAM中的存放地址,这里又对它们中的部分寄存器的各个位做了定义,也就是说,这些各个位做了定义的寄存器,它们的每一个位是可以单独进行操作的。


例如STEB EAEA1,表示开总中断,EA又是IE寄存器的最高位,这里单独对它进行操作,可以免去对整个IE寄存器做赋值操作,优化程序


 


通过这些知识的复习,我觉得下一步该动手写程序感受一下了。


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /3 下一条