<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51手記之寄存器&尋址篇

          51手記之寄存器&尋址篇

          作者: 時間:2016-11-29 來源:網(wǎng)絡(luò) 收藏
          題記:剛開始練51時就用C語言,現(xiàn)在想再加強(qiáng)一下匯編,所以不得不對單片機(jī)的硬件結(jié)構(gòu),特別是地址空間的分配方面詳細(xì)的做一下了解了。于是決定拿起課本北航的《智能化測量控制儀表原理與設(shè)計》重新學(xué)一遍。書本是基礎(chǔ),然后應(yīng)該把自己的一些應(yīng)用體會實例什么的也加上去,這樣學(xué)起來就事半功倍了畢竟這是再學(xué)習(xí)不是入門了。

          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í),我覺得下一步該動手寫程序感受一下了


          關(guān)鍵詞: 51手記寄存器尋

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();