熱門: 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
|
發(fā)布時(shí)間: 2019-6-27 22:28
正文摘要:如圖,高位地址給P2,低位地址給R2,但是程序里根本沒有P2,程序里是不是高位給R2,低位給R0了,大家看看 |
| 鎖存地址用的ALE信號(hào),也會(huì)在MOVX指令執(zhí)行時(shí),由30腳的ALE/PRO管腳輸出,這個(gè)時(shí)候,請(qǐng)樓主仔細(xì)看懂MOVX指令的讀寫周期時(shí)序圖了。單片機(jī)的指令,一定要結(jié)合單片機(jī)的特點(diǎn)來(lái)學(xué)習(xí)。畢竟有些指令是和單片機(jī)的硬件結(jié)構(gòu)有關(guān)的,不是單純的寄存器之間的數(shù)據(jù)轉(zhuǎn)移。 |
|
樓主提供的圖片,看不完全。雖然使用的是2864,但是如果2864第八位地址以外的引腳結(jié)成固定地址,MPU只想訪問(wèn)低八位地址對(duì)應(yīng)的RAM空間的時(shí)候,完全可以使用MOVX A , @Ri和MOVX @Ri, A來(lái)讀寫2864。比如說(shuō): 1、2864的A8到A12引腳都接地了,那么MPU通過(guò)MOVX A , @Ri和MOVX @Ri, A來(lái)讀寫2864的空間地址就是0x0000~0x00FF; 2、2864的A8到A12引腳都接VCC了,那么MPU通過(guò)MOVX A , @Ri和MOVX @Ri, A來(lái)讀寫2864的空間地址就是0x1F00~0x1FFF; 通常訪問(wèn)外部ROM或者RAM時(shí),由于P0口被分時(shí)使用,所以在硬件上會(huì)加一個(gè)地質(zhì)鎖存功能的芯片,比如74HC373之類的,在P0口輸出地址的時(shí)候,把地址鎖存在74HC373中。 |
|
樓主需要搞清楚MOVX @Ri, A(i=0/1)這條指令執(zhí)行時(shí),對(duì)單片機(jī)而言。會(huì)有什么動(dòng)作。單純地看只是個(gè)傳送數(shù)據(jù)的指令而已。實(shí)際上,當(dāng)執(zhí)行MOVX @R0, A這條指令時(shí),R0中保存的8位數(shù)據(jù),是用來(lái)訪問(wèn)外部RAM的低八位地址,A中保存的是要輸出的8位數(shù)據(jù)。執(zhí)行指令時(shí),低八位地址會(huì)從P0口送出,尋址范圍是256個(gè)單元,同時(shí),P3.6管腳會(huì)出現(xiàn)一個(gè)的低電平信號(hào),用來(lái)啟動(dòng)目標(biāo)RAM的WR寫允許。按照時(shí)序,P0口輸出地址后,會(huì)接著輸出數(shù)據(jù)。所以P0是被分時(shí)使用的。此時(shí),P2口不是尋址空間高八位,仍然可以作為普通IO口使用。 如果希望訪問(wèn)的對(duì)象空間大于256.可以使用MOVX @DPTR,A這條指令。同樣,數(shù)據(jù)保存在A中,對(duì)象RAM的地址保存在DPTR中,這個(gè)時(shí)候,P2口是地址高八位的輸出口,P0仍然分時(shí)復(fù)用,先輸出第八位地址,然后是輸出8位數(shù)據(jù)。 MOVX @Ri, A和MOVX A, @Ri的不同之處在于,指令執(zhí)行后,產(chǎn)生低電平的引腳是不一樣的,一個(gè)是P3.6,用作寫RAM;一個(gè)是P3.7,用于讀RAM。P3.6和P3.7都是端口復(fù)用的引腳。同時(shí),數(shù)據(jù)流向也不一樣,前者是輸出數(shù)據(jù)給RAM,P0口輸出萬(wàn)地址后,會(huì)接著輸出數(shù)據(jù)。而MOVX A, @R指令是在P0口輸出玩第八位地址后,接著等待輸入外部RAM傳給MPU的8位數(shù)據(jù)。 |
Y_G_G 發(fā)表于 2019-6-29 11:54 哥,我也是增加點(diǎn)基礎(chǔ)知識(shí),了解單片機(jī)最基礎(chǔ)的東西。我知道這個(gè)已經(jīng)過(guò)時(shí)了。 |
|
你拼了命的去研究霸王龍的生活習(xí)性,然后回家種香蕉,有多大意義呢? 1.這個(gè)程序非常不嚴(yán)謹(jǐn),實(shí)際中用不了,DPTR,R0的初始值沒有確定,程序有問(wèn)題 2.猛的搞那么一段代碼出來(lái),絕大多數(shù)人不會(huì)知道它在實(shí)際電路中能有什么用 3.所用器件已經(jīng)過(guò)時(shí)了,現(xiàn)在沒有人用這玩意,也就沒有人知道怎么真正的寫完一個(gè)完整的程序出來(lái) 4.這破爛一樣的程序沒頭沒尾的,給誰(shuí)都不會(huì)知道R0從哪里來(lái),DPTR的值是多少,作者也不想寫,就像是走走過(guò)場(chǎng),應(yīng)付一下的把這代碼交代出來(lái)而已 以下才是匯編真正完整樣子,可以燒錄到單片機(jī)中正確運(yùn)行,有晶振頻率,端口指定,電路編號(hào),備注 ;===============基于STC8的4*USB充電電流電壓顯示器===============================================; ;名稱:基于STC8的4*USB充電電流電壓顯示器 ; ;作者:老玉 ; ;日期:2019/03/14 ; ;功能:可以顯示4個(gè)USB充電端口的充電電流 ; ;單片機(jī)型號(hào):STC8A4K32S2A12 ; ;電路與PCB編號(hào):YGG_190314.0_DA ; ;晶振:使用片上的24.0MHZ振蕩電路 ; ;功能: ; ;最后更新日期:20190320 ; ;備注說(shuō)明; 程序已經(jīng)測(cè)試OK ; ;如果電流數(shù)據(jù)不對(duì),就把電路中四個(gè)運(yùn)放放大電路的增益改成50倍,如果是對(duì)的,就不用改動(dòng) ; ; ;================================================================================================ ;端口指定======================================================================================== P4 EQU 0C0H ;P4 端口的地址 P5 EQU 0C8H ;P5端口的地址 OUT EQU P0 ;P0作為輸出端口 ;==================================================================================================== ;12864顯示屏的端口指定=============================================================================== RS BIT P1.2 ; RW BIT P1.1 ; E BIT P1.0 ; PSB BIT P3.6 ; RST_12864 BIT P3.5 ; ;==================================================================================================== ;標(biāo)志位指定========================================================================================== MODE BIT 20H ;設(shè)定模式標(biāo)示位 MIAO BIT 21H ;秒閃標(biāo)志位 I_FU BIT 24H ;完全顯示標(biāo)志位 ;==================================================================================================== ;STC8的端口IO模式控制寄存器指定====================================================================== P0M0 EQU 094H ; P0M1 EQU 093H ;控制P0端口輸出模式的寄存器 P1M0 EQU 092H ; P1M1 EQU 091H ;控制P1端口輸出模式的寄存器 P2M0 EQU 096H ; P2M1 EQU 095H ;控制P2端口輸出模式的寄存器 P3M0 EQU 0B2H ; P3M1 EQU 0B1H ;控制P3端口輸出模式的寄存器 P4M0 EQU 0B4H ; P4M1 EQU 0B3H ;控制P4端口輸出模式的寄存器 P5M0 EQU 0CAH ; P5M1 EQU 0C9H ;控制P5端口輸出模式的寄存器 ;==================================================================================================== ;STC8的ADC相關(guān)寄存器指定============================================================================= ADCCFG DATA 0DEH ;ADC配置寄存器 ADC_CONTR DATA 0BCH ;ADC控制寄存器 ADC_RES DATA 0BDH ;ADC緩沖器高4位 ADC_RESL DATA 0BEH ;ADC緩沖器低8位 ADC_P13 EQU 083H ;P13ADC端口 ADC_P14 EQU 084H ;P14ADC端口 ADC_P15 EQU 085H ;P15ADC端口 ADC_P16 EQU 086H ;P16ADC端口 ADC_P17 EQU 087H ;P17ADC端口 ;==================================================================================================== WDT_CONTR EQU 0C1H ;看門狗地址 COUNT DATA 030H ;存放計(jì)數(shù)用的 COUNT_1 DATA 031H ;計(jì)數(shù)用的 DATA_BUF DATA 032H ;運(yùn)算過(guò)程中用到的數(shù)據(jù)緩存器 COUNT_2 DATA 033H ;計(jì)數(shù)用的 TWIN DATA 035H ; LED_1 DATA 036H ;個(gè)位保存器 LED_10 DATA 037H ;十位保存器 LED_100 DATA 038H ;百位保存器 LED_1000 DATA 039H ;千位保存器 DIV_L DATA 03AH ;除法高位用的緩存器 DIV_H DATA 03BH ;除法低位用的緩存器 DATA_BUF_L DATA 03CH ;數(shù)據(jù)暫存器的低位 DATA_BUF_H DATA 03DH ;數(shù)據(jù)暫存器的高位 ADC_SUM_H DATA 03FH ;ADC累加計(jì)算的高位存儲(chǔ)器 ADC_SUM_L DATA 040H ;ADC累加計(jì)算的低位存儲(chǔ)器 ADDR_12864 DATA 041H ;指定12864的顯示地址 DEL_1 DATA 042H ;延時(shí)用的 DEL_2 DATA 04FH ;誤差值存放用的寄存 D_P14 DATA 050H ;通道0誤差值 D_P15 DATA 051H ;通道1誤差值 D_P16 DATA 052H ;通道2誤差值 D_P17 DATA 053H ;通道3誤差值 ADC_ADD_H DATA 054H ;ADC總電流計(jì)算的高位存儲(chǔ)器 ADC_ADD_L DATA 055H ;ADC總電流計(jì)算的低位存儲(chǔ)器 I_OUT DATA 056H ;用于提示有沒有充電電流的寄存器 I_ALL_L DATA 057H ;用于保存總電流的低位數(shù) I_ALL_H DATA 058H ;用于保存總電流的高位數(shù) ;程序開始============================================================================================== ORG 0000H JMP STAR ORG 0100H STAR: MOV ADCCFG,#02FH ;設(shè)置ADC的時(shí)鐘和轉(zhuǎn)換結(jié)果存放格式 MOV 0BAH,#80H ;地址位于XDATA區(qū),要訪問(wèn)之前,必須先把0BAH地址中的EAXFR位置位才能訪問(wèn),只有用MOVX @DPTR,A和MOVX A,@DPTR讀寫 MOV A,#00000111B ;選擇P1.0,P1.1,P1.2內(nèi)部上拉電阻 MOV DPTR,#0FE11H ; MOVX @DPTR,A ; MOV A,#0FFH ;選擇P2內(nèi)部上拉電阻 MOV DPTR,#0FE12H ; MOVX @DPTR,A ; MOV A,#11111111B ;選擇P4內(nèi)部上拉電阻 MOV DPTR,#0FE14H ; MOVX @DPTR,A ; MOV 0BAH,#00 ; MOV P0M1,#00000000B ; MOV P0M0,#00000000B ;P0測(cè)定成默認(rèn)的傳統(tǒng)8051端口 MOV P1M1,#11111000B ;P1.0 P1.1 P1.2作為傳統(tǒng)端口,P1.3 P1.4 P1.5 P1.6 P1.7作為ADC端口 MOV P1M0,#00000000B ; MOV P2M1,#00000000B ; MOV P2M0,#00000000B ; MOV P3M1,#00000000B ; MOV P3M0,#00000000B ; MOV P4M1,#00000000B ;P4端口設(shè)定 MOV P4M0,#00000000B ; MOV P5M1,#00000000B ;P5端口設(shè)定 MOV P5M0,#00000000B ; CALL RESET_12864 ;12864初始化 CALL MUTE_12864 ; MOV COUNT_1,#5 ; MOV COUNT_2,#100 ; MOV SP,#080H ; MOV WDT_CONTR,#24H ;設(shè)定看門狗 ;====================================================================================================== MAIN: CALL DISPLAY_VIN CALL DISPLAY_AD1 CALL DISPLAY_AD0 CALL DISPLAY_AD2 CALL DISPLAY_AD3 CALL DISP_I_ALL CPL MIAO CALL MUTE_12864 ; MAIN_END: ORL WDT_CONTR,#10H ;看門狗清除 CALL DELAY ;延時(shí)一次 DJNZ COUNT_2,MAIN_END ;延長(zhǎng)顯示和ADC的時(shí)間,使顯示看起來(lái)更加穩(wěn)定 MOV COUNT_2,#250 ; JMP MAIN ;================================================================================================================ ;顯示通道P1.3 顯示輸入電壓 顯示地址:095H,最后顯示的單位是"V"=86 DISPLAY_VIN: SETB I_FU ; MOV A,#ADC_P13 ;選擇通道 CALL ADC_P1 ;選擇該通道進(jìn)行ADC MOV ADDR_12864,#085H;選擇顯示的地址 MOV R1,#86 ;<<<====最后顯示的單位是"V"=86 CALL DISPLAY_ADC ;顯示 CLR I_FU ; MOV I_ALL_L,#0 ; MOV I_ALL_H,#0 ; RET ;================================================================================================================ ;================================================================================================================ ;顯示通道P1.4 顯示充電電流 顯示地址:08CH,最后顯示的單位是"A"=65 DISPLAY_AD0: MOV A,#ADC_P14 ;選擇通道 CALL ADC_P1 ;選擇該通道進(jìn)行ADC MOV ADDR_12864,#08CH;選擇顯示的地址 MOV R1,#65 ;<<<====最后顯示的單位是"A"=65 CALL DISPLAY_ADC ;顯示 MOV A,#09CH ;<<<===選擇要顯示的地址 CALL WRITE12864_INS ;寫入地址 JNB MIAO,DISPLAY_AD0_1; MOV I_OUT,#32 ;秒到了就顯示空白 DISPLAY_AD0_1: MOV A,I_OUT ; CALL WRITE12864_DATA ; RET ;================================================================================================================ ;================================================================================================================ ;顯示通道P1.7 顯示充電電流 顯示地址:08EH,最后顯示的單位是"A"=65 DISPLAY_AD1: MOV A,#ADC_P17 ;選擇通道 CALL ADC_P1 ;選擇該通道進(jìn)行ADC MOV ADDR_12864,#08AH;選擇顯示的地址 MOV R1,#65 ;<<<====最后顯示的單位是"A"=65 CALL DISPLAY_ADC ;顯示 MOV A,#09AH ;<<<===選擇要顯示的地址 CALL WRITE12864_INS ;寫入地址 JNB MIAO,DISPLAY_AD1_1; MOV I_OUT,#32 ;秒到了就顯示空白 DISPLAY_AD1_1: MOV A,I_OUT ; CALL WRITE12864_DATA ; RET ;================================================================================================================ ;================================================================================================================ ;顯示通道P1.5 顯示充電電流 顯示地址:088H,最后顯示的單位是"A"=65 DISPLAY_AD2: MOV A,#ADC_P15 ;選擇通道 CALL ADC_P1 ;選擇該通道進(jìn)行ADC MOV ADDR_12864,#08EH;選擇顯示的地址 MOV R1,#65 ;<<<====最后顯示的單位是"A"=65 CALL DISPLAY_ADC ;顯示 MOV A,#09EH ;<<<===選擇要顯示的地址 CALL WRITE12864_INS ;寫入地址 JNB MIAO,DISPLAY_AD2_1; MOV I_OUT,#32 ;秒到了就顯示空白 DISPLAY_AD2_1: MOV A,I_OUT ; CALL WRITE12864_DATA ; RET ;================================================================================================================ ;================================================================================================================ ;顯示通道P1.6 顯示充電電流 顯示地址:08AH,最后顯示的單位是"A"=65 DISPLAY_AD3: MOV A,#ADC_P16 ;選擇通道 CALL ADC_P1 ;選擇該通道進(jìn)行ADC MOV ADDR_12864,#088H;選擇顯示的地址 MOV R1,#65 ;<<<====最后顯示的單位是"A"=65 CALL DISPLAY_ADC ;顯示 MOV A,#098H ;<<<===選擇要顯示的地址 CALL WRITE12864_INS ;寫入地址 JNB MIAO,DISPLAY_AD3_1; MOV I_OUT,#32 ;秒到了就顯示空白 DISPLAY_AD3_1: MOV A,I_OUT ; CALL WRITE12864_DATA ; RET ;================================================================================================================ DISP_I_ALL: SETB I_FU ; MOV A,I_ALL_L ; SUBB A,#30 ;總電流小于30.不顯示 MOV A,I_ALL_H ; SUBB A,#0 ; JNC DISP_I_ALL_1 ; MOV I_ALL_L,#0 ; MOV I_ALL_H,#0 ; DISP_I_ALL_1: MOV A,I_ALL_H ; MOV B,I_ALL_L ; CALL DATA_DISP ;處理總電流數(shù)據(jù) MOV ADDR_12864,#094H;選擇顯示的地址 MOV R1,#65 ;<<<====最后顯示的單位是"A"=65 CALL DISPLAY_ADC ;顯示 MOV I_ALL_H,#0 ; MOV I_ALL_L,#0 ;顯示完一次總電流就要?dú)w零一次 CLR I_FU ; RET ;===================================================================================== ;ADC_P1 使用到的共用寄存器: A B R0 COUNT DEL_1 DEL_2 ;調(diào)用此程序之前,要先把通道選擇放入A,把誤差什放入R0 ;轉(zhuǎn)換完成之后,ADC結(jié)果的高位存放在:ADC_SUM_H,低位存放在:ADC_SUM_L ;功能:進(jìn)行ADC轉(zhuǎn)換,并把轉(zhuǎn)換結(jié)果進(jìn)行平均,此子程序一共進(jìn)行10次ADC,再平均得到最后的數(shù)據(jù) ADC_P1: MOV ADC_CONTR,A ;選擇ADC通道A,A要在進(jìn)入ADC之前先指定好 MOV COUNT,#8 ;ADC一共在進(jìn)行16次,然后再平均 MOV ADC_RES,#0 ; MOV ADC_RESL,#0 ; MOV ADC_SUM_L,#0 ; MOV ADC_SUM_H,#0 ;ADC的兩個(gè)累加存儲(chǔ)先清除 ADC_P1_1: CLR C ; MOV A,#01000000B ; ORL ADC_CONTR,A ;使用"或"啟動(dòng)ADC ADC_P1_2: MOV A,#00100000B ; ANL A,ADC_CONTR ; JZ ADC_P1_2 ; ANL ADC_CONTR,#11011111B;清除ADC中斷標(biāo)志位 CLR C MOV A,ADC_RESL ;高位值傳送到緩存器 ADD A,ADC_SUM_L ;ADC運(yùn)算結(jié)果的低位相加 MOV ADC_SUM_L,A ;把運(yùn)算結(jié)果保存到累加存儲(chǔ)器 MOV A,ADC_RES ; ADDC A,ADC_SUM_H ;ADC運(yùn)算結(jié)果的高位相加 MOV ADC_SUM_H,A ;把運(yùn)算結(jié)果保存到累加存儲(chǔ)器 DJNZ COUNT,ADC_P1_1 ;一共要進(jìn)行10次的ADC MOV COUNT,#2 ; ADC_LOOP: CLR C MOV A,ADC_SUM_H RRC A MOV ADC_SUM_H,A MOV A,ADC_SUM_L RRC A MOV ADC_SUM_L,A DJNZ COUNT,ADC_LOOP ;以上進(jìn)行的是ADC之后累加值的平均 ;===========================================; MOV R0,#03 ;默認(rèn)顯示為愛心 CLR C ; MOV A,ADC_SUM_L ; SUBB A,#20 ;R0為誤差值存放寄存器 MOV A,ADC_SUM_H ; SUBB A,#0 ; JNC ADC_END_1 ;C為0就表示ADC的結(jié)果是大于20的 MOV R0,#32 ;32為空格,就是不顯示,空白 ADC_END_1: CLR C MOV I_OUT,R0 ;送充電指示標(biāo)志 MOV A,ADC_SUM_L SUBB A,#04 ;04是固有的誤差 MOV A,ADC_SUM_H ; SUBB A,#0 ; JNC ADC_END_2 ; MOV ADC_SUM_L,#0 ; MOV ADC_SUM_H,#0 ; ADC_END_2: MOV A,ADC_SUM_H ;高位ADC的結(jié)果存放到A MOV B,ADC_SUM_L ;低位ADC的結(jié)果存放到B ;===============計(jì)算總電流================================================ CLR C MOV A,I_ALL_L ; ADD A,ADC_SUM_L ; MOV I_ALL_L,A ; MOV A,I_ALL_H ; ADDC A,ADC_SUM_H ; MOV I_ALL_H,A ; ;======================================================================= MOV A,ADC_SUM_H ;高位ADC的結(jié)果存放到A MOV B,ADC_SUM_L ;低位ADC的結(jié)果存放到B CALL DATA_DISP ;對(duì)ADC轉(zhuǎn)換結(jié)果的高低位進(jìn)行拆分,拆分成4個(gè)數(shù)分別存放在4個(gè)地址 RET ;=================================================================================== ;DATA_DISP==============數(shù)據(jù)拆分,把一個(gè)數(shù)拆分成四個(gè)數(shù),用于顯示====================== ;把16進(jìn)制的高低兩個(gè)字節(jié)分別放到A和B,處理之后,個(gè)十百千位會(huì)分別放到4個(gè)地址中,使用減法運(yùn)算來(lái)達(dá)到除法的效果 ;進(jìn)入之前要先把高位數(shù)據(jù)存放到A,低位數(shù)據(jù)存放到B DATA_DISP: MOV LED_1,#0 MOV LED_10,#0 MOV LED_100,#0 MOV LED_1000,#0 ;先把四個(gè)清除 MOV DATA_BUF_H,A ; MOV DATA_BUF_L,B ;把數(shù)據(jù)傳送到緩沖器中 MOV R0,#0E8H ; MOV R1,#03H ;1000的16進(jìn)制為03E8H MOV R2,#100 MOV R3,#10 MOV R4,#0 SUB_1000: CLR C MOV A,DATA_BUF_L SUBB A,R0 MOV DIV_L,A; MOV A,DATA_BUF_H; SUBB A,R1 MOV DIV_H,A JC SUB_100 MOV DATA_BUF_L,DIV_L MOV DATA_BUF_H,DIV_H INC LED_1000 JMP SUB_1000 SUB_100: CLR C MOV A,DATA_BUF_L SUBB A,R2 MOV DIV_L,A MOV A,DATA_BUF_H; SUBB A,R4 MOV DIV_H,A JC SUB_10 MOV DATA_BUF_L,DIV_L MOV DATA_BUF_H,DIV_H INC LED_100 JMP SUB_100 SUB_10: MOV A,DATA_BUF_L MOV B,R3 DIV AB MOV LED_10,A MOV LED_1,B RET ;============================================================================ ;這一段是把拆分之后的四個(gè)數(shù)字的數(shù)據(jù)分別關(guān)去查表,并用于12864的顯示 ;調(diào)用程序之前: 要先把準(zhǔn)備顯示的地址放到ADDR_12864 要顯示的單位放到 R1 ;四個(gè)顯示的數(shù)值要先分解好放到四個(gè)地址中 DISPLAY_ADC: MOV A,LED_1 ; MOV DPTR,#TAB2 ; MOVC A,@A+DPTR ; MOV LED_1,A ; MOV A,LED_10 ; MOV DPTR,#TAB2 ; MOVC A,@A+DPTR ; MOV LED_10,A ; MOV A,LED_100 ; MOV DPTR,#TAB2 ; MOVC A,@A+DPTR ; MOV LED_100,A ; MOV A,LED_1000 ; MOV DPTR,#TAB2 ; MOVC A,@A+DPTR ; MOV LED_1000,A ; MOV A,ADDR_12864 ;<<<<=====寫入要顯示的地址 LCALL WRITE12864_INS ; MOV A,LED_1000 ; CALL WRITE12864_DATA ;顯示千位 MOV A,#46 ;顯示點(diǎn)"." CALL WRITE12864_DATA ;顯示點(diǎn) MOV A,LED_100 ; CALL WRITE12864_DATA ;顯示百位 JNB I_FU,D_A_2 ;如果不是在顯示總電流就直接不顯示后面的,只要1.0 這種形式 D_A_1: MOV A,LED_10 ; CALL WRITE12864_DATA ;顯示十位 MOV A,LED_1 ; CALL WRITE12864_DATA ;顯示個(gè)位 MOV A,R1 ;<<<<=====寫入在最后顯示的單位 CALL WRITE12864_DATA ;顯示最后的單位 D_A_2: ; CALL DELAY ; RET ;=============================================================================== ;===================延時(shí)子程序================================================== DELAY: MOV DEL_2,#50 MS5DISP1: MOV DEL_1,#255 DJNZ DEL_1,$ DJNZ DEL_2,MS5DISP1 RET ;===================向12864寫入數(shù)據(jù)============================================= WRITE12864_DATA: CALL ASK_BF ;查BF是否忙 SETB RS CLR RW MOV OUT,A SETB E CLR E CALL DELAY RET ;===================向12864寫入指令============================================= WRITE12864_INS: CALL ASK_BF ;查BF是否忙 CLR RS CLR RW MOV OUT,A SETB E CLR E CALL DELAY RET ;===================查BF是否忙================================================== ASK_BF: MOV OUT,#0FFH ;釋放P0端口 CLR RS SETB RW SETB E JB OUT.7,ASK_BF CLR E CALL DELAY RET ;================================================================================ ;================================================================================================================ ;菜單顯示 MUTE_12864: MOV A,#080H ;把要顯示的地址傳送到顯示的緩沖器上 LCALL WRITE12864_INS ;寫入要顯示的地址 MOV DPTR,#TAB3 ; MUTE_1: CLR A ; MOVC A,@A+DPTR ;查表 JZ MUTE_2 ;A的值為0就表示已經(jīng)讀到了最后一個(gè)內(nèi)容了 CALL WRITE12864_DATA ;調(diào)用寫入數(shù)據(jù)子程序 INC DPTR ;地址加1,顯示下一個(gè)地址的數(shù)據(jù) JMP MUTE_1 ;再去查表顯示 MUTE_2: MOV A,#090H ;把要顯示的地址傳送到顯示的緩沖器上 LCALL WRITE12864_INS ;寫入要顯示的地址 MOV DPTR,#TAB4 ; MUTE_2_1: CLR A ; MOVC A,@A+DPTR ;查表 JZ MUTE_END ;A的值為0就表示已經(jīng)讀到了最后一個(gè)內(nèi)容了 CALL WRITE12864_DATA ;調(diào)用寫入數(shù)據(jù)子程序 INC DPTR ;地址加1,顯示下一個(gè)地址的數(shù)據(jù) JMP MUTE_2_1 ;再去查表顯示 MUTE_END: RET ;============================================================================================== ;================================================================================================================ ;12864初始化 RESET_12864: CLR RST_12864 ;12864復(fù)位 RESET_1: CALL DELAY ;延時(shí) DJNZ R0,RESET_1 ; SETB RST_12864 ;關(guān)閉12864復(fù)位 SETB PSB ;8位數(shù)據(jù)模式 MOV A,#06H ;設(shè)定整體顯示 LCALL WRITE12864_INS ;寫入指令 MOV A,#030H ;設(shè)定使用基本指令 LCALL WRITE12864_INS ;寫入指令 MOV A,#0CH ;設(shè)定顯示狀態(tài)開關(guān) LCALL WRITE12864_INS ;寫入指令 MOV A,#01H ;清除屏幕 LCALL WRITE12864_INS ;寫入指令 RET ;================================================================================================================ ORG 1000H TAB2: DB '0123456789' ;顯示數(shù)字的0-9 TAB3: DB '電源電壓',':',0H ;以0H作為結(jié)果標(biāo)志 TAB4: DB '總電流',':',0H ; END |
lwh999995 發(fā)表于 2019-6-28 01:30 還是不太明白,我現(xiàn)在把程序一條一條的讀給你聽 wr2 MOVX A,@DPTR 外部地址的數(shù)據(jù)給累加器 MOV R2,A 累加器數(shù)值給寄存器。它用的是MOV指令,應(yīng)該是給單片機(jī)內(nèi)部的寄存器 MOVX @R0,A 累加器數(shù)值給2864A的R0寄存器,問(wèn)題是R0是哪里來(lái)的,沒有說(shuō)明 INC DPTR 地址指針加一 INC R0 目的地址指針加一 cjne R0,#00H,NEXT 地址指針未滿,轉(zhuǎn)NEXT INC R2 注釋上說(shuō)是高位指針加一,,但是題目上R2是低位地址啊?P2是2864A的高位地址 NEXT DJNZ R1,WR2 頁(yè)面未裝滿轉(zhuǎn)移 DEC R0 恢復(fù)最后寫的數(shù)據(jù)地址 LOOP: MOVX A,@R0 讀2864A數(shù)據(jù)給累加器 XRL A,R2 與寫入的最后一個(gè)數(shù)據(jù)相異或,,這個(gè)為什么寫這個(gè)指令啊,不太明白 R2應(yīng)該是最開始存入的數(shù)據(jù)。 JB ACC.7, LOOP 最高位不等,LOOP 什么作用 RET |
| P2是指P2IO口吧 |
Powered by 單片機(jī)教程網(wǎng)