我用0809和C51做了一个电压表,其中电路接法如下:用通道0做模拟量输入,其他没用的通道和Vref(-)一起接模拟地(模拟地和模拟电源+用直流稳压电源给出);VREF(+)接数字电源+5V;数据线接P0,ADDA,ADDB,ADDC分别接单片几的A0,A1,A2(经过373),时钟500KHZ,EOC经过反相器接中断1,P2.0和WR,RD 经过两或非门分别连ST,ALE,OE. 硬件连接检查了几遍没有连接错误的地方,编程是地址没错,但是在用仿真器调试的时候从0809出来的数据为全1,一直保持不变化,请问是不是0809没有被启动吗?请问各位大虾这是原理错误呢还是程序的问题? com equ 20H ;命令存储单元 dat equ 21H ;数据存储单元 dat1 equ 22h ;0809输出数据存储 hun equ 23h ;0809转换完的数据的百位数BCD码存放单元 ten equ 24h ;十位 date equ 25h ;个位 biao bit 50h ;数据处理标志位 int3 equ 0fe00h ;ADC0809通道3地址,电压测量输入通道 cw_adr equ 0ff20h ;写命令地址 cr_adr equ 0ff60h ;读命令地址 dw_adr equ 0ffa0h ;写数据地址 dr_adr equ 0ffe0h ;读数据地址 over data 2fh
org 0000h ljmp bejin ;转初始化 org 0013h ljmp serve ;转中断服务程序 org 0100h ;**************初始化************ bejin:mov sp,#70h mov psw,#00h ;clr a mov hun,#30h mov ten,#30h mov date,#30h mov dat,a mov dat1,a clr biao setb it1 setb ex1 setb ea lcall lcdint ;***************主循环*********** main: ;lcall adc lcall bcd0 lcall lcd lcall time sjmp main ;****************数据处理******** bcd0: jnb biao,ty lcall bcd2 clr biao ty: ret ;***************LCD显示程序****** lcd: lcall disply1 lcall disply3 lcall disply2 lcall disply4 ret ;*************第一行显示*********** disply1:MOV COM,#80H ;LCD第一行字符的DDRAM首地址 LCALL WC ;送DDRAM地址,AC指向显示第一行的第一个字符 MOV DPTR,#DATA1 ;取要显示的第一行字符的首地址 MOV R6,#0 ;每行字符的当前位置 Mov R7,#16 ;R7作字符计数器 LCALL WRN ret ;*************第二行显示*********** disply2:MOV COM,#90H ;LCD第二行字符的DDRAM首地址 LCALL WC ;送DDRAM地址,AC指向显示第二行的第二个字符 MOV DPTR,#DATA2 ;取要显示的第二行字符的首地址 MOV R6,#0 ;每行字符的当前位置 MOV R7,#16 ;R7作字符计数器 LCALL WRN ret ;*************第三行显示*********** disply3:MOV COM,#88H ;LCD第三行字符的DDRAM首地址 LCALL WC ;送DDRAM地址,AC指向显示第三行的第三个字符 MOV DPTR,#DATA3 ;取要显示的第三行字符的首地址 MOV R6,#0 ;每行字符的当前位置 MOV R7,#16 ;R7作字符计数器 LCALL WRN1 ret ;*************第四行显示*********** disply4:MOV COM,#98H ;LCD第四行字符的DDRAM首地 LCALL WC ;送DDRAM地址,AC指向显示第四行的第四个字符 MOV DPTR,#DATA4 ;取要显示的第四行字符的首地址 MOV R6,#0 ;每行字符的当前位置 MOV R7,#16 ;R7作字符计数器 LCALL WRN ret ;****************LCD初始化************** lcdint: MOV COM,#30H MOV R7,#2 LOOP: LCALL WC LCALL DELAY DJNZ R7,LOOP ;写两次30h命令,软件复位 LCALL DELAY MOV COM,#0cH ;设置开显示,光标关显示,关闪烁 LCALL WC LCALL DELAY MOV COM,#01H ;清屏 LCALL WC LCALL DELAY MOV COM,#06H ;设置AC加1计数,画面不动 LCALL WC LCALL DELAY ret ;*************LCD写控制指令************** WC: PUSH DPH PUSH DPL PUSH ACC ACALL BUSY MOV DPTR,#CW_ADR MOV A,COM ;写命令COM MOVX @DPTR,A ;RS=0,R/W=0写命令 POP ACC POP DPL POP DPH RET
;*************LCD写一位字符数据********** WD: PUSH DPH PUSH DPL PUSH ACC ACALL BUSY MOV DPTR,#DW_ADR MOV A,DAT ;写命令DAT MOVX @DPTR,A ;RS=1,R/W=0写命令 POP ACC POP DPL POP DPH RET ;************LCD显示子程序************* WRN: MOV A,R6 MOVC A,@A+DPTR INC R6 MOV DAT,A LCALL WD DJNZ R7,WRN RET ;**********第三行专用显示程序********** WRN1: CJNE R6,#10,LOOP1 mov a,hun ;mov dptr,#tab ;movc a,@a+dptr inc r6 mov dat,a lcall wd loop1: cjne r6,#12,loop2 mov a,ten ;mov dptr,#tab ;movc a,@a+dptr inc r6 mov dat,a lcall wd mov a,date ;mov dptr,#tab ;movc a,@a+dptr inc r6 mov dat,a lcall wd loop2: MOV A,R6 MOVC A,@A+DPTR INC R6 MOV DAT,A LCALL WD DJNZ R7,WRN1 RET ;**************LCD判忙子程序************ BUSY: PUSH DPH PUSH DPL PUSH ACC MOV DPTR,#CR_ADR BF: MOVX A,@DPTR JB ACC.7,BF POP ACC POP DPL POP DPH RET ;**********启动ADC0809转换程序*********** adc: mov dptr,#int3 ;取0809通道int3的地址 ;mov a,#00h movx @dptr,a ;写入任意一个数,启动a/d转换 ret ;*************中断服务程序*************** serve: push a ;保护现场 push psw push dpl push dph mov dptr,#int3 ;采集数据 movx a,@dptr cpl a jz tt cpl a mov dat1,a setb biao tt: pop dph pop dpl pop psw pop a reti ;r6,r7 *******数据处理*************** bcd: mov a,dat1 ;n*100/51=n*2 mov b,#2 mul ab mov r6,b ;高字节 mov r5,a ;低字节 mov R4,#100 ;r4 lcall dv ;取百位 mov a,r5 add a,#30h mov hun,a mov a,R6 ;r5 mov b,#10 div ab add a,#30h mov ten,a mov a,b add a,#30h mov date,a ret ;************16位/8位子程序******** ;被除数放在R6、R5,除数放在R4中 ;r5放商,R6为余数 dv: mov r7,#08h ; s0: clr c mov a,r5 rlc a mov r5,a mov a,r6 rlc a mov 07h,c clr c subb a,r4 jb 07h,s1 jnc s1 add a,r4 sjmp s2 s1: inc r5 s2: mov r6,a djnz r7,s0 ret ;*********************************** bcd1: mov a,dat1 mov b,#100 mul ab mov r5,b mov r4,a mov r6,#51 mov r7,#0 lcall dudiv mov a,r5 mov r6,a mov a,r4 mov r5,a mov r4,#100 lcall dv mov a,r5 add a,#30h mov hun,a mov a,r6 mov b,#10 div ab add a,#30h mov ten,a mov a,b add a,#30h mov date,a ret bcd2: mov a,#186 mov b,#51 div ab add a,#30h mov hun,a mov a,b mov b,#100 mul ab mov r6,b mov r5,a mov r4,#51 lcall dv mov a,r5 mov b,#10 div ab add a,#30h mov ten,a mov a,b add a,#30h mov date,a ret ;**************16位/16位************* ;被除数存放在R5、R4中,除数存放在R7、R6中 ;出口信息:商存放在R5、R4中,余数存放R3、R2中 dudiv: mov a,r7 ;取除数高位字节 jnz start ;除数不为0则转移 mov a,r6 jz error start: mov a,r5 jnz start1 mov a,r4 jnz start1 ret start1:clr a mov r2,a mov r3,a mov r1,#16 div0: clr c mov a,r4 rlc a mov r4,a mov a,r5 rlc a mov r5,a mov a,r2 rlc a mov r2,a mov a,r3 rlc a mov r3,a mov a,r2 subb a,r6 jc next inc r4 mov r3,a mov a,r0 mov r2,a next: djnz r1,div0 mov a,r3 jb acc.7,round mov a,r2 rlc a mov r2,a mov a,r3 rlc a subb a,r7 jc done jnz round mov a,r2 subb a,r6 jc done round: mov a,r4 add a,#1h mov r4,a mov a,r5 addc a,#0h mov r5,a done: mov over,#0h ret error: mov over,#0ffh ret ;**************1MS延时子程序********** DELAY: MOV R0,#08H DLY0: MOV R1,#0C8H DLY1: DJNZ R1,DLY1 DJNZ R0,DLY0 RET
;***********1S延时子程序************ time:MOV R2,#5 M1:MOV R1,#200 M2:MOV R0,#248 M3:DJNZ R0,M3 DJNZ R1,M2 DJNZ R2,M1 RET ;*********汉字表**************** DATA1:db' 数字式电压表 ' DATA2:db' INT3 ' DATA3:db' 电压值: . V ' DATA4:db' ' ;***********数字表*********************** tab:db'0123456789' end
|