找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3251|回复: 8
收起左侧

单片机高位地址给P2,低位地址给R2,但是程序里根本没有P2,请高手看下

[复制链接]
ID:450037 发表于 2019-6-27 22:28 来自手机 | 显示全部楼层 |阅读模式
如图,高位地址给P2,低位地址给R2,但是程序里根本没有P2,程序里是不是高位给R2,低位给R0了,大家看看
Screenshot_20190627-125923.jpg
回复

使用道具 举报

ID:207421 发表于 2019-6-28 01:30 | 显示全部楼层
一行一行的看代码,再看看这张图,就明白了
指令.JPG
回复

使用道具 举报

ID:10947 发表于 2019-6-28 09:59 | 显示全部楼层
P2是指P2IO口吧
回复

使用道具 举报

ID:450037 发表于 2019-6-29 08:17 | 显示全部楼层
lwh999995 发表于 2019-6-28 01:30
一行一行的看代码,再看看这张图,就明白了

还是不太明白,我现在把程序一条一条的读给你听
wr2  MOVX A,@DPTR  外部地址的数据给累加器
       MOV   R2,A    累加器数值给寄存器。它用的是MOV指令,应该是给单片机内部的寄存器
       MOVX  @R0,A  累加器数值给2864A的R0寄存器,问题是R0是哪里来的,没有说明
       INC  DPTR   地址指针加一
       INC  R0      目的地址指针加一
       cjne  R0,#00H,NEXT    地址指针未满,转NEXT
        INC   R2    注释上说是高位指针加一,,但是题目上R2是低位地址啊?P2是2864A的高位地址
NEXT    DJNZ   R1,WR2     页面未装满转移
            DEC  R0    恢复最后写的数据地址
LOOP:  MOVX   A,@R0   读2864A数据给累加器
          XRL       A,R2    与写入的最后一个数据相异或,,这个为什么写这个指令啊,不太明白 R2应该是最开始存入的数据。
          JB    ACC.7, LOOP    最高位不等,LOOP 什么作用
           RET
回复

使用道具 举报

ID:401564 发表于 2019-6-29 11:54 | 显示全部楼层
你拼了命的去研究霸王龙的生活习性,然后回家种香蕉,有多大意义呢?
1.这个程序非常不严谨,实际中用不了,DPTR,R0的初始值没有确定,程序有问题
2.猛的搞那么一段代码出来,绝大多数人不会知道它在实际电路中能有什么用
3.所用器件已经过时了,现在没有人用这玩意,也就没有人知道怎么真正的写完一个完整的程序出来
4.这破烂一样的程序没头没尾的,给谁都不会知道R0从哪里来,DPTR的值是多少,作者也不想写,就像是走走过场,应付一下的把这代码交代出来而已
以下才是汇编真正完整样子,可以烧录到单片机中正确运行,有晶振频率,端口指定,电路编号,备注


;===============基于STC8的4*USB充电电流电压显示器===============================================;
;名称:基于STC8的4*USB充电电流电压显示器                                                                                                                        ;
;作者:老玉                                                                                                                                                                                ;
;日期:2019/03/14                                                                                                                                                                ;
;功能:可以显示4个USB充电端口的充电电流                                                                                                                        ;
;单片机型号:STC8A4K32S2A12                                                                                                                                                ;
;电路与PCB编号:YGG_190314.0_DA                                                                                                                                        ;
;晶振:使用片上的24.0MHZ振荡电路                                                                                                                                        ;
;功能:                                                                                                                                                                                        ;
;最后更新日期:20190320                                                                                                                                                        ;
;备注说明; 程序已经测试OK                                                                                                                                                ;                               
;如果电流数据不对,就把电路中四个运放放大电路的增益改成50倍,如果是对的,就不用改动                                ;                                                                                                                                ;
;================================================================================================
;端口指定========================================================================================
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        ;
;====================================================================================================
;标志位指定==========================================================================================
MODE                        BIT                20H                ;设定模式标示位
MIAO                        BIT                21H                ;秒闪标志位
I_FU                                BIT                24H                ;完全显示标志位
;====================================================================================================
;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相关寄存器指定=============================================================================
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        ;存放计数用的
COUNT_1                        DATA        031H        ;计数用的
DATA_BUF                DATA        032H        ;运算过程中用到的数据缓存器
COUNT_2                        DATA        033H        ;计数用的
TWIN                        DATA        035H        ;
LED_1                        DATA        036H        ;个位保存器
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        ;数据暂存器的低位
DATA_BUF_H                DATA        03DH        ;数据暂存器的高位
ADC_SUM_H                DATA        03FH        ;ADC累加计算的高位存储器
ADC_SUM_L                DATA        040H        ;ADC累加计算的低位存储器
ADDR_12864                DATA        041H        ;指定12864的显示地址
DEL_1                        DATA        042H        ;延时用的
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总电流计算的高位存储器
ADC_ADD_L                DATA        055H        ;ADC总电流计算的低位存储器
I_OUT                        DATA        056H        ;用于提示有没有充电电流的寄存器
I_ALL_L                        DATA        057H        ;用于保存总电流的低位数
I_ALL_H                        DATA        058H        ;用于保存总电流的高位数
;程序开始==============================================================================================
                                        ORG                0000H
                                        JMP                STAR
                                        ORG                0100H
STAR:                                MOV                ADCCFG,#02FH        ;设置ADC的时钟和转换结果存放格式
                                        MOV                0BAH,#80H                ;地址位于XDATA区,要访问之前,必须先把0BAH地址中的EAXFR位置位才能访问,只有用MOVX        @DPTR,A和MOVX        A,@DPTR读写
                                        MOV                A,#00000111B        ;选择P1.0,P1.1,P1.2内部上拉电阻
                                        MOV                DPTR,#0FE11H        ;
                                        MOVX        @DPTR,A                        ;
                                        MOV                A,#0FFH                        ;选择P2内部上拉电阻
                                        MOV                DPTR,#0FE12H        ;
                                        MOVX        @DPTR,A                        ;
                                        MOV                A,#11111111B        ;选择P4内部上拉电阻
                                        MOV                DPTR,#0FE14H        ;
                                        MOVX        @DPTR,A                        ;
                                        MOV                0BAH,#00                ;                                               
                                        MOV                P0M1,#00000000B        ;
                                        MOV                P0M0,#00000000B        ;P0测定成默认的传统8051端口
                                        MOV                P1M1,#11111000B        ;P1.0 P1.1 P1.2作为传统端口,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端口设定
                                        MOV                P4M0,#00000000B        ;
                                        MOV                P5M1,#00000000B        ;P5端口设定
                                        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        ;设定看门狗
;======================================================================================================
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                                ;延时一次
                                        DJNZ        COUNT_2,MAIN_END        ;延长显示和ADC的时间,使显示看起来更加稳定
                                        MOV                COUNT_2,#250                ;
                                        JMP          MAIN
;================================================================================================================
;显示通道P1.3           显示输入电压        显示地址:095H,最后显示的单位是"V"=86
DISPLAY_VIN:                        SETB        I_FU                        ;
                                        MOV                A,#ADC_P13                ;选择通道
                                        CALL        ADC_P1                        ;选择该通道进行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                        ;选择该通道进行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                        ;选择该通道进行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                        ;选择该通道进行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                        ;选择该通道进行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                ;处理总电流数据
                                        MOV                ADDR_12864,#094H;选择显示的地址
                                        MOV                R1,#65                        ;<<<====最后显示的单位是"A"=65
                                        CALL        DISPLAY_ADC                ;显示
                                        MOV                I_ALL_H,#0                ;
                                        MOV                I_ALL_L,#0                ;显示完一次总电流就要归零一次
                                        CLR                I_FU                        ;
RET
;=====================================================================================
;ADC_P1   使用到的共用寄存器:        A B R0 COUNT DEL_1 DEL_2
;调用此程序之前,要先把通道选择放入A,把误差什放入R0
;转换完成之后,ADC结果的高位存放在:ADC_SUM_H,低位存放在:ADC_SUM_L
;功能:进行ADC转换,并把转换结果进行平均,此子程序一共进行10次ADC,再平均得到最后的数据
ADC_P1:                        MOV                ADC_CONTR,A                        ;选择ADC通道A,A要在进入ADC之前先指定好
                                MOV                COUNT,#8                        ;ADC一共在进行16次,然后再平均
                                MOV                ADC_RES,#0                        ;
                                MOV                ADC_RESL,#0                        ;
                                MOV                ADC_SUM_L,#0                ;
                                MOV                ADC_SUM_H,#0                ;ADC的两个累加存储先清除
ADC_P1_1:                CLR                C                                        ;
                                MOV                A,#01000000B                ;
                                ORL                ADC_CONTR,A                        ;使用"或"启动ADC
ADC_P1_2:                MOV                A,#00100000B                ;
                                 ANL                A,ADC_CONTR                        ;
                                JZ                ADC_P1_2                        ;
                                ANL                ADC_CONTR,#11011111B;清除ADC中断标志位
                                CLR                C
                                MOV                A,ADC_RESL                        ;高位值传送到缓存器
                                ADD                A,ADC_SUM_L                        ;ADC运算结果的低位相加
                                MOV                ADC_SUM_L,A                        ;把运算结果保存到累加存储器
                                MOV                A,ADC_RES                        ;
                                ADDC        A,ADC_SUM_H                        ;ADC运算结果的高位相加
                                MOV                ADC_SUM_H,A                        ;把运算结果保存到累加存储器
                                DJNZ        COUNT,ADC_P1_1                ;一共要进行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                ;以上进行的是ADC之后累加值的平均
;===========================================;
                                MOV                R0,#03                                ;默认显示为爱心
                                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的结果是大于20的
                                MOV                R0,#32                                ;32为空格,就是不显示,空白
ADC_END_1:                CLR                C
                                MOV                I_OUT,R0                        ;送充电指示标志
                                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的结果存放到A               
                                MOV                B,ADC_SUM_L                    ;低位ADC的结果存放到B
;===============计算总电流================================================
                                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的结果存放到A               
                                MOV                B,ADC_SUM_L                    ;低位ADC的结果存放到B
                                CALL        DATA_DISP                        ;对ADC转换结果的高低位进行拆分,拆分成4个数分别存放在4个地址                                               
RET
;===================================================================================
;DATA_DISP==============数据拆分,把一个数拆分成四个数,用于显示======================
;把16进制的高低两个字节分别放到A和B,处理之后,个十百千位会分别放到4个地址中,使用减法运算来达到除法的效果
;进入之前要先把高位数据存放到A,低位数据存放到B               
DATA_DISP:                MOV                LED_1,#0
                                   MOV                LED_10,#0
                                   MOV                LED_100,#0
                                   MOV                LED_1000,#0                ;先把四个清除
                                   MOV                DATA_BUF_H,A        ;
                                   MOV                DATA_BUF_L,B        ;把数据传送到缓冲器中
                                   MOV                R0,#0E8H                ;
                                   MOV                R1,#03H                        ;1000的16进制为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
;============================================================================
;这一段是把拆分之后的四个数字的数据分别关去查表,并用于12864的显示
;调用程序之前:  要先把准备显示的地址放到ADDR_12864 要显示的单位放到 R1
;四个显示的数值要先分解好放到四个地址中
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                        ;显示点"."
                                CALL        WRITE12864_DATA        ;显示点
                                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        ;显示个位
                                MOV                A,R1                        ;<<<<=====写入在最后显示的单位
                                CALL        WRITE12864_DATA        ;显示最后的单位
D_A_2:                ;        CALL        DELAY                        ;                          
RET
;===============================================================================
;===================延时子程序==================================================
DELAY:                             MOV         DEL_2,#50
        MS5DISP1:                MOV         DEL_1,#255
                                        DJNZ         DEL_1,$
                                        DJNZ         DEL_2,MS5DISP1
RET
;===================向12864写入数据=============================================
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就表示已经读到了最后一个内容了
                                        CALL         WRITE12864_DATA        ;调用写入数据子程序
                                        INC         DPTR                        ;地址加1,显示下一个地址的数据
                                        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就表示已经读到了最后一个内容了
                                        CALL         WRITE12864_DATA        ;调用写入数据子程序
                                        INC         DPTR                        ;地址加1,显示下一个地址的数据
                                        JMP         MUTE_2_1                ;再去查表显示                       
MUTE_END:                       
RET
;==============================================================================================
;================================================================================================================
;12864初始化
RESET_12864:                       CLR                RST_12864                ;12864复位
RESET_1:                               CALL               DELAY                        ;延时
                                        DJNZ        R0,RESET_1                ;
                                        SETB        RST_12864                ;关闭12864复位
                                        SETB         PSB                         ;8位数据模式                                                                                                  
                                        MOV         A,#06H                         ;设定整体显示
                                        LCALL         WRITE12864_INS        ;写入指令
                                        MOV         A,#030H                 ;设定使用基本指令
                                        LCALL         WRITE12864_INS  ;写入指令
                                        MOV         A,#0CH                         ;设定显示状态开关
                                        LCALL         WRITE12864_INS        ;写入指令
                                        MOV         A,#01H                         ;清除屏幕
                                        LCALL         WRITE12864_INS        ;写入指令
RET
;================================================================================================================
ORG 1000H
TAB2:                        DB        '0123456789'                ;显示数字的0-9
TAB3:                        DB        '电源电压',':',0H        ;以0H作为结果标志
TAB4:                        DB        '总电流',':',0H                ;
END

回复

使用道具 举报

ID:450037 发表于 2019-6-29 13:10 | 显示全部楼层
Y_G_G 发表于 2019-6-29 11:54
你拼了命的去研究霸王龙的生活习性,然后回家种香蕉,有多大意义呢?
1.这个程序非常不严谨,实际中用不了 ...

哥,我也是增加点基础知识,了解单片机最基础的东西。我知道这个已经过时了。
回复

使用道具 举报

ID:517466 发表于 2019-6-29 13:58 | 显示全部楼层
楼主需要搞清楚MOVX @Ri, A(i=0/1)这条指令执行时,对单片机而言。会有什么动作。单纯地看只是个传送数据的指令而已。实际上,当执行MOVX @R0, A这条指令时,R0中保存的8位数据,是用来访问外部RAM的低八位地址,A中保存的是要输出的8位数据。执行指令时,低八位地址会从P0口送出,寻址范围是256个单元,同时,P3.6管脚会出现一个的低电平信号,用来启动目标RAM的WR写允许。按照时序,P0口输出地址后,会接着输出数据。所以P0是被分时使用的。此时,P2口不是寻址空间高八位,仍然可以作为普通IO口使用。
如果希望访问的对象空间大于256.可以使用MOVX @DPTR,A这条指令。同样,数据保存在A中,对象RAM的地址保存在DPTR中,这个时候,P2口是地址高八位的输出口,P0仍然分时复用,先输出第八位地址,然后是输出8位数据。
MOVX @Ri, A和MOVX A, @Ri的不同之处在于,指令执行后,产生低电平的引脚是不一样的,一个是P3.6,用作写RAM;一个是P3.7,用于读RAM。P3.6和P3.7都是端口复用的引脚。同时,数据流向也不一样,前者是输出数据给RAM,P0口输出万地址后,会接着输出数据。而MOVX A, @R指令是在P0口输出玩第八位地址后,接着等待输入外部RAM传给MPU的8位数据。
回复

使用道具 举报

ID:517466 发表于 2019-6-29 14:09 | 显示全部楼层
楼主提供的图片,看不完全。虽然使用的是2864,但是如果2864第八位地址以外的引脚结成固定地址,MPU只想访问低八位地址对应的RAM空间的时候,完全可以使用MOVX A , @Ri和MOVX  @Ri, A来读写2864。比如说:
1、2864的A8到A12引脚都接地了,那么MPU通过MOVX A , @Ri和MOVX  @Ri, A来读写2864的空间地址就是0x0000~0x00FF;
2、2864的A8到A12引脚都接VCC了,那么MPU通过MOVX A , @Ri和MOVX  @Ri, A来读写2864的空间地址就是0x1F00~0x1FFF;
通常访问外部ROM或者RAM时,由于P0口被分时使用,所以在硬件上会加一个地质锁存功能的芯片,比如74HC373之类的,在P0口输出地址的时候,把地址锁存在74HC373中。
回复

使用道具 举报

ID:517466 发表于 2019-6-29 14:15 | 显示全部楼层
锁存地址用的ALE信号,也会在MOVX指令执行时,由30脚的ALE/PRO管脚输出,这个时候,请楼主仔细看懂MOVX指令的读写周期时序图了。单片机的指令,一定要结合单片机的特点来学习。毕竟有些指令是和单片机的硬件结构有关的,不是单纯的寄存器之间的数据转移。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表