ADC0808和AT89C51利用LCD的数字电压表

来源:互联网 发布:spss130统计软件 编辑:程序博客网 时间:2024/04/29 23:01

 刚学了单片机,学校要求我们做课设!题目是:ADC0808和AT89C51利用LCD的数字电压表!

经过自己和老师的努力做了出来!上网查过,大都是LED的还没有LCD的!就发表上来了!

源程序如下:

COM EQU 50H ; 指令寄存器
DAT EQU 51H ; 数据寄存器

RS EQU P2.1 ; LCD寄存器选择信号
RW EQU P2.2 ; LCD读/写选择信号
E EQU P2.3 ; LCD使能信号

        ORG 0000H
        LJMP MAIN       ;主程序入口
        ORG 000BH
        LJMP BT0        ;T0中断入口

        ORG 0030H       ;主程序,初始化
MAIN:   MOV SP,#60H
        LCALL INT
        MOV 30H,#30H
        MOV 31H,#0A5H
        MOV 32H,#30H
        MOV 33H,#30H
        MOV 34H,#30H
        MOV R7,#30H
        LCALL N1         ;显示班级和姓名 Voltage = 0.000       
MOV TMOD,#00H    ;定时器T0设为方式0
MOV TH0,#00h    ;装入定时常数
MOV TL0,#00h
SETB TR0        ;启动T0
MOV 24h, #03h   ;装入T0中断次数
MOV IE,#82H     ;开中断
LP: MOV R7,#30H     ;显示缓冲区首地址
LCALL DISPLY
SJMP LP         ;循环显示

DISPLY:
   mov com,#0CAH         ;设置数据起始地址(第而行第10位)
   lcall pr1
   mov r1,#05h
   mov r0,#30h
l: MOV DAT,@r0
   LCALL PR2
   INC R0
   djnz r1,l
   ret

;1. 逐字依次输入方式演示程序段
N1:MOV COM,#01H       ;清屏
   LCALL PR1
   MOV COM,#06H       ;设置输入方式
   LCALL PR1
   MOV COM,#081H       ;设置数据起始地址(第一行地二位)
   LCALL PR1
   MOV DPTR,#TAB1
   MOV R2,#0EH
   MOV R3,#00H
WRIN1:
   MOV A,R3
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL PR2
   INC R3
   DJNZ R2,WRIN1
   MOV COM,#0C1H       ;设置数据起始地址(第二行地二位)
   LCALL PR1
   MOV DPTR,#TAB2
   MOV R2,#9
   MOV R3,#00H
WRIN2:
   MOV A,R3
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL PR2
   INC R3
   DJNZ R2,WRIN2
   RET
TAB1: DB "XG10501 Jin ke"
TAB2: DB "VOLTAGE=      "


; LCD间接控制方式下的初始化子程序
INT:
LCALL DELAY ; 调延时子程序
MOV COM,#38H ; 设置工作方式(2行,8位数据)
LCALL PR1
MOV COM,#01H ; 清屏
LCALL PR1
MOV COM,#06H ; 设置输入方式
LCALL PR1
MOV COM,#0CH ; 设置显示方式
LCALL PR1
RET

DELAY:MOV R6,#0FH ; 延时子程序
MOV R7,#00H
DELAY1: NOP
DJNZ R7,DELAY1
DJNZ R6,DELAY1
RET


;LCD间接控制方式的驱动子程序如下

;1 读BF和AC值
PR0: PUSH ACC
     MOV P0,#0FFH ; P0置位, 准备读
     CLR RS ; RS=0
     SETB RW; R/W=1
     SETB E ; E=1
     LCALL DELAY
     MOV COM,P0 ; 读BF和AC6-4值
     CLR E ; E=0
     POP ACC
     RET

;2 写指令代码子程序
PR1: PUSH ACC
     CLR RS    ; RS=0
     SETB RW   ; R/W=1
PR11:MOV P0,#0FFH; P0置位, 准备读
     SETB E ; E=1
     LCALL DELAY
     NOP
     MOV A,P0
     CLR E
     JB ACC.7,PR11;BF=1?
     CLR RW; R/W=0
     MOV P0,COM
     SETB E ; E=1
     CLR E ; E=0; E=0
     POP ACC
     RET

;3 写显示数据子程序
PR2:PUSH ACC
    CLR RS ; RS=0
    SETB RW; R/W=1
PR21:MOV P0,#0FFH
    SETB E ; E=1
    LCALL DELAY
    MOV A,P0 ; 读BF和AC6-4值
    CLR E ; E=0
    JB ACC.7,PR21
    SETB RS
    CLR RW
    MOV P0,DAT; 写入数据
    SETB E
    CLR E
    POP ACC
    RET

;4 读显示数据子程序
PR3:PUSH ACC
    CLR RS ; RS=0
    SETB RW; R/W=1
PR31:MOV P0,#0FFH ; P0置位, 准备读
    SETB E ; E=1
    LCALL DELAY
    MOV A,P0 ; 读BF和AC6-4值
    CLR E ; E=0
    JB ACC.7,PR31
    SETB RS
    SETB RW; R/W=1
    MOV P0,#0FFH ; 读数据
    SETB E ; E=1
    MOV DAT,P0
    CLR E ; E=0
    POP ACC
    RET

; 定时器T0中断服务程序,读取ADC0809第0通道的A/D转换结果并化为显示值
BT0:PUSH ACC         ;保护现场
PUSH PSW
MOV PSW,#08H
CLR TR0          ;停止T0
MOV TH0,#00h     ;重装定时常数
MOV TL0,#00h
MOV DPTR,#0F6FFH ;0809端口地址
MOV A,#0         ;0通道
MOVX @DPTR,A ;启动0809
MOV R7,#0FFH      ;等待A/D转换完
DJNZ R7,$
MOVX A,@DPTR ;读0809转换结果
        MOV B,#03H       ;将转换的值除以3再累加,存入40H中
        DIV AB
        ADD A,40H
        MOV 40H,A
        MOV A,B           ;将除以3后的余数累加放入41H中
        ADD A,41H
        MOV 41H,A
        dec 24h           ;3次中断未到则返回
mov a,24h
jnz rtn1
        mov 24h,#03h     ;重装中断次数
        MOV A,41H        ;将累加的余数再除3后相加
        DIV AB
        ADD A,40H
        MOV 40H,#0       ;清零累加数
        MOV 41H,#0
rtn:    MOV B,#05h       ;A/D转换结果化为显示值
MUL AB           ;(AD*5)/256
mov 30h,b        ;AD*5的高字节为整数部分
mov b,#0ah
mul ab           ;AD*5的低字节为/256的结果,为小数部分
mov 32h,b        ;二进制小数换为10进制数
mov b,#0ah
mul ab
mov 33h,b
mov b,#0ah
mul ab
mov 34h,b
ljmp rtn1
rtn1: SETB TR0
        ORL 30H,#30H      ;显示值换为ASSIC码
        mov 31H,#0a5H    ;小数点
        ORL 32H,#30H
        ORL 33H,#30H
        ORL 34H,#30H
        POP PSW
POP ACC
RETI

    END

 

原创粉丝点击