51手記之寄存器&尋址篇
51單片機(jī)的存儲器結(jié)構(gòu):
在物理上可以分為4個存儲器空間:即片內(nèi)ROM,片外ROM,片內(nèi)RAM,片外RAM。51/52單片機(jī)有64KB(2的16次方,16條地址線尋址)的ROM地址空間。其中51有4KB的片內(nèi)ROM,52有8KB的片內(nèi)ROM。至于使用片內(nèi)還是片外的存儲器,可以靠控制信號EA腳來設(shè)置,當(dāng)從片內(nèi)存儲器開始取指令時,EA腳接正(對于ROM型單片機(jī),通常采取此方式),此時如果指令地址超過4KB空間,則自動從片外開始取指令。而如果不使用片內(nèi)存儲器只從片外存儲器取指令時,將EA接地即可。
ROM中有些單元是保留給系統(tǒng)使用的:0000-0002H單元是所有執(zhí)行程序的入口地址,復(fù)位后程序總是從0000H單元開始執(zhí)行。(所以在匯編的開始總是一句
ORG0000
LJMPnnnn;主程序中斷入口
這個語句的意思是在0000這個地址上存放著LJMP nnnn這個語句,這里的nnnn是程序的入口地址,也就是編程者希望上電后程序從哪個地方開始執(zhí)行)。
0003-002AH單元均勻的分為5段,用于5個中斷服務(wù)程序的入口。(例如
ORG00BH
LJMPBT0;TO中斷入口
也就是說00BH上存放著LJMP BTO這個語句,當(dāng)產(chǎn)生TO中斷時,前提當(dāng)然是此中斷處于開啟狀態(tài)了,程序?qū)?zhí)行該語句,然后跳轉(zhuǎn)到BT0所指的地址上的程序繼續(xù)執(zhí)行)。
51/52的片內(nèi)數(shù)據(jù)存儲器RAM有256Byte,其中00H-7FH地址空間是直接尋址區(qū)。該區(qū)從00H-1FH是工作寄存器區(qū),有4組工作寄存器組,至于使用哪一組則有PSW的RS0和RS1的狀態(tài)決定。片內(nèi)RAM的20H-2FH地址為位尋址區(qū)。片內(nèi)RAM的80H-FFH地址空間是特殊功能寄存器(SFR)區(qū)。52系列有26個特殊功能寄存器。下面就把頭文件reg52.h里的部分內(nèi)容貼出來。(對于寄存器地址參考頭文件就足夠了,對于別的一些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;
關(guān)于MCU的時鐘問題:
一般用的是12MHz的晶體,而MCU執(zhí)行一個機(jī)器周期需要12各時鐘周期(所謂時鐘周期,就是指晶體振蕩一個周期的時間),那么正好是1us,一般的指令需要1-2個機(jī)器周期即可完成,乘除指令的運(yùn)算量比較大需要4各機(jī)器周期。
尋址方式:
51單片機(jī)有7種尋址方式。
1、寄存器尋址:前面提到了內(nèi)部RAM中的00H-1FH地址單元作為工作寄存器使用。一共是有32各地址單元,分成四組,每組有8個寄存器,命名為R0-R7,每次可以使用其中的一組。當(dāng)使用R0-R7來表示操作數(shù)時,就屬于寄存器尋址方式。
例如:MOVA,R0;把寄存器R0的內(nèi)容送入累加器A中
2、直接尋址:在指令中直接給出操作數(shù)地址,就屬于直接尋址方式。此時指令的操作數(shù)部分直接是操作數(shù)的地址。
例如:MOV A,2AH;把RAM地址2AH的內(nèi)容送入累加器A中
3、立即尋址:
例如:MOV A,#3AH;該指令就是表示把立即數(shù)3AH送入累加器A中,立即數(shù)前加上一個#,和直接尋址方式區(qū)分
4、寄存器間接尋址:若以寄存器的名稱直接給出操作數(shù)的地址,則稱為寄存器間接尋址。
例如:MOV A,@R0;該指令是把RO里的內(nèi)容作為地址,這個地址的數(shù)據(jù)送入累加器A,注意前面需要加@
5、變址尋址:變址尋址是以某個寄存器的內(nèi)容為基本的地址,然后在這個基址上加以地址的偏移量,才是真正的操作數(shù)地址。
例如:MOV A,@A+DPTR;地址是A+DPTR的值,這個地址的內(nèi)容送如累加器A
6、相對尋址:相對轉(zhuǎn)移指令需要用到相對尋址方式,此時操作數(shù)部分給出的是地址的相對偏移量部分。
目的地址=源地址+指令字節(jié)數(shù)+ rel(rel可正可負(fù))
例如: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;
從前面的特殊功能寄存器地址里已經(jīng)了解了它們在RAM中的存放地址,這里又對它們中的部分寄存器的各個位做了定義,也就是說,這些各個位做了定義的寄存器,它們的每一個位是可以單獨進(jìn)行操作的。
例如STEB EA;EA置1,表示開總中斷,EA又是IE寄存器的最高位,這里單獨對它進(jìn)行操作,可以免去對整個IE寄存器做賦值操作,優(yōu)化程序
通過這些知識的復(fù)習(xí),我覺得下一步該動手寫程序感受一下了
評論