單片機開發商深圳英銳恩分享PIC單片機16F84內部硬件資源,PIC16F84單片機點亮一只發光二極管的源程序實例是為了說明PIC單片機16F84具體應用時的基本格式。
現在我們已經知道要單片機工作,就需用匯編語言編制程序。而對某個PIC單片機編程時,還需對選用的PIC單片機內部硬件資源有所了解。這里介紹PIC16F84單片機的內部結構,如圖1所示的框圖。由圖1看出,其基本組成可分為四個主要部分,即運算器ALU和工作寄存器W;程序存儲器;數據存儲器和輸入/輸出(I/O)口;堆棧存儲器和定時器等?,F分別介紹如下。
1運算器ALU及工作寄存器W
運算器ALU是一個通用算術、邏輯運算單元,用它可以對工作寄存器W和任何通用寄存器中的兩個數進行算術(如加、減、乘、除等)和邏輯運算(如與、或、異或等)。16F84是八位單片機,ALU的字長是八位。在有兩個操作數的指令中,典型的情況是一個操作數在工作寄存器W中,而另一個操作數是在通用寄存器中,或者是一個立即數。在只有一個操作數的情況下,該數要么是在工作寄存器W中,要么是在通用寄存器中。W寄存器是一個專用于ALU操作的寄存器,它是不可尋址的。
根據所執行的指令,ALU還可能會影響框圖中狀態寄存器STATUS的進位標志C、全零標志Z等。
2程序存儲器
單片機內存放程序指令的存儲器稱為程序存儲器。PIC16F84的所有指令字長為14位。所以程序存儲器的各存儲單元是14位寬。一個存儲單元存放一條指令。16F84的程序存貯器有1024(28)個存儲單元(存儲容量為1k)。這些程序存儲器都是由FPEROM構成的。
程序存儲器是由程序計數器PC尋址的。16F84的程序計數器為13位寬,可尋址8K(8×1024)的程序存儲器空間,但16F84實際上只使用了1k的空間(單元地址為0~3FFH)。當訪問超過這些地址空間的存儲單元時,將導致循環回到有效的存儲空間。
對于用過其它單片機的用戶,可能會感到16F84的片內存儲器容量太少了。實際上并非如此,因為16F84的指令系統都是由單字指令構成的,相應于其它由二字節、三字節甚至四字節指令的單片機而言,PIC單片機的程序存儲器有效容量要比標稱值擴大25倍到3倍
3 數據存儲器
在單片機PIC16F84中,除了有存放程序的程序存儲器外,還有數據存儲器。單片機在執行程序過程中,往往需要隨時向單片機輸入一些數據,而且有些數據還可能隨時改變。在這種情況下就需用數據存儲器。由于數據存儲器不但要能隨時讀取存放在其各個單元內的數據,而且還需隨時寫進新的數據,或改寫原來的數據。因此,數據存儲器需由隨機存儲器RAM構成。RAM存儲器在斷電時,所存數據隨即丟失,這在實際應用中有時會帶來不便。但是,在16F84單片機中有64×8位E2PROM數據存儲器。存放在E2PROM中的數據在斷電時不會丟失。
16F84單片機中的RAM數據存儲器如表1所示,該RAM分為兩個存儲體:即存儲體0(Bank0)和存儲體1(Bank1)。每個存儲體均可以直接用內部總線傳送信息,所以它們都是以寄存器方式工作和尋址。這些八位寄存器,又可分為通用寄存器和專用寄存器兩個部分。通用寄存器存放數據,專用寄存器存放控制單片機運作的信息。每個存儲體最大可擴展到7FH(128個字節)。在每個存儲體中,專用寄存器被安排在低位地址空間,通用寄存器被安排在高位地址空間。
通用寄存器用法單一,但專用寄存器卻各有各的用處,現將較基本的專用寄存器作一簡單介紹。
(1)程序計數器(PCL、PCLATH)。程序計數器PC是對程序進行管理的計數器。PIC16F84的程序計數器為13位寬,最大可尋址的存儲空間為8k×14位。實際上16F84只使用前1k×14位(0000~03FFH)存儲空間。因程序計數器有13位寬,而專用寄存器只有8位。因此PC由兩個專用寄存器構成。其低八位PCL是一個可讀/寫寄存器(地址為02H或82H),而高字節PCH(有效位5位)不能直接進行讀/寫操作,它是通過一個8位的保持寄存器PCLATH(地址為0A或8AH)把高5位地址傳送給程序計數器的高字節。當執行CALL、GOTO指寫PCL時,PC值的高字節就從PCLATH寄存器中裝入。
(2)狀態寄存器STATUS。狀態寄存器STATUS含有算術邏輯單元ALU運算結果的狀態(如有無進位等)、復位狀態及數據存儲體選擇位。有關位位的設定如表2所示,功能如下:
1)第0位。進位/借位位C。執行加、減運算指令
表2
IRP RP1 RP0 TO PD Z DC C
后,若結果有進位或借位,則C被置1,否則置0。在執行移位指令時,也要用到這一位。
2)第1位。輔助進位/借位位DC。執行加、減運算指令后,若結果的低四位向高四位有進位或借位,則DC置1,否則置0。
3)第2位。零標志位運算結果為零,Z被置1;運算結果不為零,Z被清零。
4)第3位。低功耗標志位PD。上電復位或執行CLRWDT指令后置1,執行SLEEP指令后被清零。
5)第4位。定時時間到標志位TO。上電復位或執行CLRWDT、SLEEP指令后被置1,監視定時器的定時時間到被清零。
6)第5位和第6位(RP0、RP1)。這兩位是用于直接尋址時的寄存器體選擇位。即00——選中Bank0(00H~7FH);01——選中Bank1(80H~FFH),16F84只有兩個存儲體。故10、11不用。
7)第7位IRP。這是間接尋址的寄存體選擇位。0——選中Bank0、1(00H~FFH),1——選中Bank2、3。16F84只有Bank0、1,所以此IRP位應被置為0。
(3)間接尋址INDF和FSR寄存器
INDF寄存器不是一個物理寄存器,而是一個邏輯功能的寄存器(地址為00H或80H),當對INDF寄存器進行尋址時,實際上是訪問FSR寄存器內容所指的單元,即把FSR寄存器作為間接寄存器使用。FSR稱為“寄存器選擇”寄存器,地址為(04H或84H)。對INDF寄存器本身進行間接尋址訪問,將讀出FSR寄存器的內容,例如當FSR=00H時,間接尋址讀出INDF的數據將為00H。用間接尋址方式寫入INDF寄存器時,雖然寫入操作可能會影響STATUS中的狀態字,但寫入的數據是無效的。
4 I/O口
單片機作為一個控制器件必定有數據輸入和輸出。輸入量可能是溫度、壓力、轉速等,而輸出量可能是開關量和數據,以保證受控過程在規定的范圍內運行。數據的輸入和輸出都需通過單片機內部有關電路,再與引腳構成輸入/輸出(I/O)端口。PIC16F84單片機芯片有兩個I/O端口(PROTA和PORTB)。端口A為5位口,端口B為8位口,共占用13位引腳。每個端口由一個鎖存器(即數據存儲器中的特殊功能寄存器05H、06H單元)、一個輸出驅動器和輸入緩沖器等組成。當把I/O口作輸出時,數據可以鎖存;作輸入口時,數據可以緩沖。
16F84 PORTA口中的RA4是斯密特觸發輸入、漏極開路輸出。而其它的RA口引腳都是TTL電平輸入和全CMOS驅動輸出。端口PORTB是一個八位雙向可編程I/O口。各端口雖然也由鎖存器、驅動器、緩沖器等構成,但因功能略有不同而導致電路亦存在差別?,F以PORTA口的RA0 ~RA3的電路(見左圖)為例,說明其基本工作原理。
圖中RA口的I/O引腳是由數據方向位(寄存器TRISA)來定義數據流向。當TRISA寄存器的位置為“1”時,其輸出驅動器(由P溝道和N溝道MOS管串接而成)呈高阻態,即兩個MOS管均截止,I/O口被定義為輸入。此時,數據由I/O端輸入,經TTL輸入緩沖器到D觸發器。當執行讀指令時,此D觸發器使能,數據經三態門進入數據總線。
當TRISA的位置為“0”時,I/O口被定義為輸出,此時輸出鎖存器的輸出電平就是I/O口的輸出電平。
讀PORTA寄存器的結果就是讀取I/O引腳上的電平,而寫PORTA寄存器的結果是寫入I/O鎖存器。所有的寫I/O口的操作都是一個“讀入/修改/寫入”的過程,即先讀I/O引腳電平,然后由程序修改(按要求給定一個值),再置入I/O鎖存器。
PIC16F84單片機的輸出可提供20mA的電流,所以它可直接驅動LED。PORTA和PORTB各個位均可分別定義為輸入和輸出。下面以PORTA口初始化程序的實例,說明選擇I/O口的方法。
CLRF PORTA;端口A被清零
BSF STATUS;狀態寄存器STATUS的RPO位置為1,選BANK1。
MOVLW 0xCF ;將定向值
;11001111置入W工作寄存器
MOVWF TRISA;置RA(3~0)位為輸入
??;RA 54位為輸出
??;TRISA 76位未用
在使用I/O口時應注意:
(1)當需要一個I/O口一會做輸入、一會又做輸出時,輸出值會不確定。
(2)I/O引腳輸出驅動電路為CMOS互補推挽輸出。當其為輸出狀態時,不能與其它輸出腳接成“線或”或“線與”,否則,會因電流過載燒壞單片機。
(3)當對I/O口進行寫操作后不宜直接進行讀操作,一般要求在兩條連續的寫、讀指令間至少加入一條NOP指令。
例:MOVWF 6 ;寫I/O
NOP ;穩定I/O電平
MOVF 6,W;讀I/O
5堆棧
單片機執行程序時,常常要執行調用子程序。這樣就產生了一個問題:如何記憶是從何處調用的子程序,以便執行子程序之后正確返回。此外,在程序執行過程中,還可能會發生中斷,轉而執行中斷子程序,這時,又如何記憶從何處中斷,以便返回呢?
滿足上述功能的方法就是“堆棧”技術。
“堆棧”是一個用來保存臨時數據的棧區。當主程序調用子程序時,單片機執行到CALL指令或發生中斷時,就自動將下一條指令的地址“壓棧”保存到棧區。當子程序結束,單片機執行返回指令時,就自動地把棧區的內容“彈出”,作為下步指令執行的新地址。
PIC16F84單片機芯片內有一個8級13位寬(與PC同寬)的硬件堆棧,此堆棧既不占用程序存儲空間,也不占用數據存儲空間。當執行一條CALL指令或一個中斷被響應后,程序計數器PC中的斷點地址就自動被壓棧(PUSH)保護,而當執行RETURN、RETLW或者RETFIE指令時,堆棧中的斷點地址會彈回(POP)程序計數器PC中。無論是PUSH還是POP操作,都不影響PCLATH寄存器的內容?!?/p>
6定時器/計數器TMRO
PIC單片機16F84中有一個定時器,此定時器也可用于計數,因此稱為定時器/計數器,符號為TMRO。TMRO可用于定時控制、延時、對外部事件計數和檢測等場合。TMRO是一個8位增量(加1)計數器。它在數據存貯器中的地址為01。定時器所用的時鐘源可以是內部系統時鐘(OSC/4,即四倍振蕩周期),也可以是外部時鐘。若TMRO對內部系統時鐘的標準脈沖系列進行計數時,就成為定時器;對外部脈沖進行計數時TMRO就成為計數器。
不管是定時還是計數方式,TMRO在對內部時鐘或對外部事件計數時,都不占用CPU時間,除非TMRO溢出,才可能中斷CPU的當前操作??梢?,定時器是單片機16F84中效率高且工作靈活的部件。
為了擴大定時或計數的范圍,配合TMRO的使用,還有一個可編程預定標器。此定標器實際上是一個可編程分頻器。
TMRO的內部結構示意圖如附圖所示。其工作方式由數據存儲器中的項選寄存器OPTION控制。OPTION是一個可讀/寫的寄存器,如附表所示。它含有配置TMRO/WDT預定標器、外部INT中斷、TMRO等的各種控制位。
TMRO的定時、計數方式是由OPTION寄存器中的D5(即TOCS位)確定。當TOCS=0時,工作于定時器方式;當TOCS=1時,工作于計數器方式。作定時器時,每個指令周期加1(無預分頻時);而作計數器時,則在每個RA4/TOCKI引腳上電平變化時加1。OPTION寄存器的位4(TOCS位)決定外部脈沖的觸發方式,當TOSE=1,下降沿觸發;TOSE=0,上升沿觸發。當TMRO內部計數器發生計數溢出(從FFh→00h)時,溢出位送入中斷控制寄存器INTCON。
由附圖可知,預分頻器也是一個8位計數器。其分頻數是由OPTION寄存器中的PS2~PS0三位值來改變。分頻數可以是以下8種之一:1∶1、1∶2、1∶4、1∶8、1∶16、1∶32、1∶64和1∶128。
當分頻器用于TMRO時,所有寫入TMRO的指令,如CLRF 1、MOVWF 1、BSF 1、等都將對預分頻器清零。需要注意的是,預分頻器是不能讀寫的。此分頻器可用于TMRO,也可用于WDT,其切換由軟件控制。為了避免意外的芯片復位,當需要切換時,必須執行相應的一段程序,以下是從WDT切換到TMRO時所需執行的程序:
CLRWDT ;
對WDT和預定標器清零
BSF STATUS,RP0 ;選中存儲體1
MOVLW B′xxxx0xxx′ ;PSA=0,選中TMRO
MOVWF OPTION ??;送入OPTION寄存器
BCF STATUS,RP0 ;復位存儲體0
7 延時和定時
在設計單片機應用系統時,經常會遇到需要使某一過程(如加溫、加壓等)持續一段時間的情況,如連續加壓1分鐘,通電2分鐘等。單片機如何正確確定這段時間呢?這里可通過兩種方式,即延時和定時來實現。試看下例。
在應用系統中要求PIC16F84單片機的RAO端控制一個發光二極管按一定頻率閃亮,可通過電路來實現。同時還必須為16F84單片機編制一個程序。由電路圖可知,要使發光二極管LED按一定的頻率閃亮,只要使RAO端輸出一個變化的高→低→高……電平即可。由此設計出如下的源程序(清單1):
list P=16F84,F=INHX8M
??;……
ORG 0
MOVLW 0 ;主程序開始
TRIS 5 ;置RA口為輸出
BCF 5,0 ;RA口0位清零
LOOP:CALL DELAY;閃動延時
COMF 5 ;RA口求反,亮—滅交替
GOTO LOOP ;循環
??;……
DELAY ;以下為延時子程序
MOVLW D′50
MOVWF 8
LOOP1:MOVWF 9
LOOP2:DECFSZ 9,F
GOTO LOOP2
DECFSZ 8,F
GOTO LOOP1
RETLW 0
由清單1可知,當主程序開始時,首先將工作寄存器W清零,然后將W寄存器的內容送TRISA寄存器,使其清零,以設置RA口為輸出。接著又將RA口的第5位清零,使LED開始時處于熄滅狀態。隨之持續一段時間,即執行延時子程序,再將RA口取反,變為高電平輸出,LED發光,再延時,又使RA口取反,LED熄滅……。這樣,LED就一暗一亮,持續交替進行。
在這里,使LED亮、暗持續一段時間是通過單片機執行延時子程序DELAY來實現的。此延時程序的核心就是讓單片機的CPU反復執行使寄存器內容減1的指令DECFSZ。即將十進制數50分別裝入通用寄存器F8、F9,以進行50×50=2500次的減1操作。如果執行一次DECFSZ指令需1個指令周期(跳轉時需2個周期),若設振蕩頻率為100kHz,即指令周期為40μs,則延時時間為2500×40=100000μs=100ms,即01秒。實際上還略為大些。此延時時間已超過人眼的視覺保留時間。因而能看清LED的明、暗交替變化。
如果我們需要更長的延時時間,可仿照上例,裝入更大的數或引入多重循環。因此,在原則上,延時時間可根據需要任意延長。
不過,采用延時程序來持續某一過程的方式有缺陷。延時就是使CPU在某幾條指令上“轉圈”,延時越長,“轉圈”數越多,這時,CPU不能再去執行其它操作,如監視溫度、濕度等。這在某些實時控制系統中,不允許這樣做。為此,在單片機16F84單片機中,專門設置了一個“鬧鐘”——定時器TMR0。需要某過程延續多長時間,可將其“撥入”TMR0,到時它會發生“中斷”,告訴CPU定時時間到。要CPU暫停其它工作,轉過來執行“中斷子程序”,完成輸出開、關信號之類的任務后,再回去執行其中斷的工作。這樣,就使CPU的工作效率提高。因而,延時的使用有局限性,采用定時器TMR0則可用于各種場合中。
8 中斷
PIC單片機16F84具有實時處理功能,能對外界異常發生的事件由中斷技術作及時處理。
當單片機的CPU正在處理某事件時,若外部發生了某一事件(如定時器溢出、引腳上電平變化),請求CPU迅速去處理,于是CPU就暫時中止當前的工作,轉去處理所發生的事件。中斷處理完該事件后,再回到原來被中止的地方,繼續執行原來的工作,如圖1所示。實現這種功能的部件稱為中斷系統。產生中斷的請求源稱為中斷源。中斷源向CPU提出的處理請求,稱為中斷請求或中斷申請。CPU暫時中斷自身的事務,轉去處理事件的過程,稱為CPU的中斷響應過程。對事件的整個處理過程,稱為中斷服務(或中斷處理)。處理完畢,再回到原來被中止的地方,稱為中斷返回。
PIC16F84單片機芯片有4種中斷源,其邏輯電路如圖2所示。
9中斷控制
中斷主要由中斷控制寄存器INTCON(圖3)來控制。INTCON是一個可讀/寫寄存器,含有定時器TMRO溢出、RB口的變化和外部INT引腳中斷等各種允許控制和標志位。
全局中斷允許位GIE(D7)置1,將開放所有未被屏蔽的中斷,如將該位清零,將禁止所有的中斷。在響應中斷時,GIE位將被清零,以禁止其它中斷,返回的斷點地址被壓棧保護,接著把中斷入口地址0004h裝入程序計數器PC。在中斷服務程序中,通過對中斷標志位進行查詢,確定中斷標志位必須在重新開放中斷之前用軟件清零,以避免不斷地中斷申請而反復進入中斷。
(1)INT中斷。RBO/INT引腳上的外部中斷由邊沿觸發,當INTEDG位(OPTION寄存器第6位)被置1時,選用上升沿觸發,如該位被清零,則由下降沿觸發。當檢測到引腳上有規定的有效邊沿時,便把INTE位(INTCON的D4位)置1。在重新開放這個中斷之前,必須在中斷服務程序中對INTE位清零?! ?2)TMRO中斷。當定時器TMRO的計數器計滿溢出(即由FFH變成00H)時,硬件自動把TOIF(INTCON的D2位)置1。其中斷可以通過對TOIE(INTCOND的D5位)置1或清零來控制該中斷是否開放。
(3)PORTB口引腳電平變化中斷。在PORTB口的D7~D0引腳上一旦有電平變化,就會把RBIF(INTCON的D0位)置1。這個中斷可以通過對RBIE(INTCON的D3位)置1或清零來控制該中斷是否開放。
(4)中斷的現場保護。在發生中斷時,只有返回斷點的地址被壓棧保護。若用戶還希望保護關鍵的寄存器(如W寄存器和STATUS寄存器)。這需要由軟件來實現。有關中斷的現場保護,請參看本報第15期有關PIC單片機指令識讀中的實例。
10 復位
復位是單片機的初始化操作。其主要功能是把程序計數器PCL初始化為000H,可使16F84單片機從000H單元開始執行程序。
PIC16F84單片機有下列幾種不同的復位方式。
(1)芯片上電復位POR。
(2)正常工作狀態下通過外部MCLR引腳加低電平復位。
(3)在省電休眠狀態下通過外部MCLR引腳加低電平復位。
(4)監視定時器WDT超時溢出復位。
PIC16F84單片機片內集成有“上電復位”POR電路,對于一般應用,只要把MCLR引腳接高電位即可。
在正常工作或休眠狀態下用MCLR復位,只需在MCLR引腳上加一按鍵瞬間接地即可。
單片機16F84復位操作,對其它一些寄存器會有影響,如表1所示。
11監視定時器WDT
單片機系統常用于工業控制,在操作現場通常會有各種干擾,可能會使執行程序彈飛到一種死循環,從而導致整個單片機控制系統癱瘓。如果操作者在場,就可進行人工復位,擺脫死循環。但操作者不能一直監視著系統,即使監視著系統,也往往是引起不良后果之后才進行人工復位。由于PIC16F84單片機中具有程序運行自動監視系統,即監視定時器WDT(Watch Dog Time),直譯為“看門狗”定時器。這好比是主人養了一條狗,主人在正常干活時總不忘每隔一段時間就給狗喂食,狗就保持安靜,不影響主人干活。如果主人打嗑睡,不干活了,到一定時間,狗餓了,發現主人還沒有給它吃東西,就會大叫起來,把主人喚醒。由此可見,WDT有如下特性:
(1)本身能獨立工作,基本上不依賴CPU。
(2)CPU在一個固定的時間間隔中和WDT打一次交通(如使其清零,即喂一次狗),以表明系統目前工作正常。
(3)當CPU落入死循環后,能被WDT及時發覺(如WDT計數溢出),并使系統復位。
PIC16F84單片機內的WDT,其定時計數的脈沖序列由片內獨立的RC振蕩器產生,所以它不需要外接任何器件就可以工作。而且這個片內RC振蕩器與OSC1/CLKIN(引腳{16})上的振蕩電路無關,即使OSC1和OSC2上的時鐘不工作,WDT照樣可以監視定時。例如:當PIC16F84在執行SLEEP指令后,芯片進入休眠狀態,CPU不工作,主振蕩器也停止工作,但是,WDT照樣可監視定時。當WDT超時溢出后,可激活(喚醒)芯片繼續正常的操作。而在正常操作期間,WDT超時溢出將產生一個復位信號。如果不需要這種監視定時功能,在固化編程時,可關閉這個功能。附圖是監視定時器的結構框圖。表2是與WDT有關的寄存器。
WDT的定時周期在不加分頻器的情況下,其基本定時時間是18ms,這個定時時間還受溫度、VDD和不同元器件的工藝參數等的影響。如果需要更長的定時周期,還可以通過軟件控制OPT/ON寄存器把預分頻器配置給WDT,這個預分頻器的最大分頻比可達到1∶128。這樣就可把定時周期擴大128倍,即達到23秒。
如果把預分頻器配置給WDT,用CLRWDT和SLEEP指令可以同時對WDT和預分頻器清零,從而防止計時溢出引起芯片復位。所以在正常情況下,必須在每次計時溢出之前執行一條CLRWDT指令(即喂一次“狗”),以避免引起芯片復位。當系統受到嚴重干擾處于失控狀態時,就不可能在每次計時溢出之前執行一條CLR WDT指令,WDT就產生計時溢出,從而引起芯片復位,從失控狀態又重新進入正常運行狀態。
當WDT計時溢出時,還會同時清除狀態寄存器中的D4位T0,檢測T0位即可知道復位是否由于WDT計時溢出引起的?! ~?/p>
12 E2PROM的使用方法
在PIC16F84單片機中,除了可直接尋址的由SRAM構成的數據存儲器外,還另有可電擦、電寫的E2PROM數據存儲器。該E2PROM共有64字節,其地址為00~3FH單元。由于E2PROM具有在線改寫,并在掉電后仍能保持數據的特點,可為用戶的特殊應用提供方便。16F84的E2PROM在正常操作時的整個VDD工作電壓范圍內是可讀寫的,典型情況下可重寫100萬次,數據保存期大于40年。
PIC16F84單片機的E2PROM并未映象在寄存器組空間中,所以它們不能像SRAM通用寄存器那樣用指令直接尋址訪問,而需要通過專用寄存器進行間接尋址操作。因此,在16F84單片機中增加了以下四個專用寄存器,即EECON1、EECON2、EEDATA、EEADR,專門用于片內對E2PROM的操作。該專用寄存器中,EEDATA存放8位讀/寫數據,EEADR存放正在被訪問的E2PROM存儲單元的地址。
EECON1是只有低五位的控制寄存器,其高三位不存在,讀作“0”。具體見下表。
D7 D6 D5 D4 D3 D2 D1 D0
- - - EEIF WRERR WREN WR RD
控制位RD和WR分別用于讀寫操作的啟動,這兩位可以由軟件置1,以啟動讀、寫操作,但不能用軟件清零,原因是防止不恰當的軟件操作會使寫入失敗。當讀寫操作完成后由硬件自動清零,表示此刻未對E2PROM進行讀寫操作。當WREN位被置1時,允許進行寫操作,而在上電時該位被清零。在正常操作時,一旦有MCLR或WDT復位,WRERR位就置1,表示寫操作被中止。當寫操作完成時,EEIF被置1(需由軟件清零);當寫操作未完成或尚未啟動時,EEIF為“0”。
EECON2僅是一個邏輯上的寄存器,而不是一個物理上存在的寄存器,讀出時將總是為零。它只在寫操作時起作用。
(1)E2PROM的讀操作
為進行一次E2PROM讀操作,需執行如下步驟:
1)將E2PROM的單元地址放入EEADR。2)置RD(EECON的D0位)=1。3)讀取EEDATA寄存器。
程序段舉例,讀取25H處的E2PROM存儲器數據:
…
BCF STATUS,RP0 ;選Bank0
MOVLW 25H
MOVWF EEADR ;地址25H→EEADR
BSF STATUS,RP0 ;選Bank1
BSF EECON1,RD ;啟動讀操作
BCF STATUS,RP0 ;選Bank0
MOVF EEDATA,W ;將E2PROM數據
… ;讀入W寄存器
(2)E2PROM的寫操作
要進行一次E2PROM寫操作,需執行如下步驟:
1)將E2PROM單元地址放入EEADR;2)將寫入數據放入EEDATA;3)執行一段控制程序段。
例如:將數據99H寫入E2PROM的25H單元,需執行下列程序:
…
BCF STATUS,RP0 ;送Bank0
MOVLW 25H
MOVWF EEADR ;地址→EEADR
MOVLW 99H
MOVWF EEDATA ;寫入數據→EEDATA
BSF STATUS,RP0??;選Bank1
BSF EECON1,WREN;寫操作功能允許
1 BCF INTCON,GIE??;關閉總中斷
2 MOVLW 0x55
3 MOVWF EECON2
4 MOVLW 0xAA
5 MOVWF EECON2 ;操作EECON2
6 BSF EECON1,WR;啟動寫操作
7 BSF INTCON,GIE ;開放總中斷
…
注意:上列程序中的2~6條各語句必須嚴格執行,否則不能啟動E2PROM的寫操作。而1~7條則是我們建議用戶執行的操作,即在E2PROM寫操作序列步驟中要關閉所有中斷,以免這個序列被中斷打斷。
另外,WREN(EECON1的D2位)是用來保證E2PROM不會被意外寫入而設置的,所以,在平時,用戶程序應保持WREN=0以禁止寫操作。只有當需對E2PROM寫入時才置WREN=1,并在寫入完成后將其恢復為0。用戶只有置WREN=1后才能置WREN=1啟動寫操作。上電復位后WREN位自動清零。
E2PROM寫操作約需10ms的時間才能完成。用戶程序可通過查詢WR位的狀態(當WR=0時表示操作已完成),或者用E2PROM寫入完成中斷來判斷E2PROM寫操作是否完成。如要使用中斷,應先置EEIF(INTCON的D6)為1,以開中斷。E2PROM寫完成要中斷標志位EEIF,只能用軟件清零。