📄 基于at89s51单片机的电压示波器(汇编)有借鉴意义.txt
字号:
写的51单片机电压示波器成功!自己庆贺一下:)
;20070519 0:46程序完工!
;* 控制器:KS0107 *
;* LCD型号:TS12864A-2或兼容型号 *
;* MCU:AT89S5* ,晶体频率:11.0592MHz *
;* 取模方式:纵向字节倒序 *
;* CS1和CS2为高电平有效 *
;***************硬件端口定义***********
RS EQU P2.0 ;即DI;12864液晶信号
RW EQU P2.1 ;12864液晶信号
E EQU P2.2 ;12864液晶信号
CS1 EQU P2.3 ;12864液晶信号
CS2 EQU P2.4 ;12864液晶信号
RST EQU P2.5 ;12864液晶信号
LVCC EQU P2.6 ;12864背景灯地址
AD_CLK EQU P1.0 ;AD0832时钟
AD_DI EQU P1.1 ;AD0832转换数据
AD_CS EQU P3.4 ;AD0832片选
COM EQU 20H ;12864指令数据寄存器
DAT EQU 21H ;12864显示数据寄存器
x equ 22h ;屏x值
AD_OPT EQU 23H ;AD采集数据状态
;#0<-①0<-②0<-③0<-④ 0<-⑤0<-⑥0<-⑦0<-⑧B位
;⑦主程序已经取走数据1为是0为否
;⑧数据是否可用? 1为是0为否
AD_DAT EQU 24H ;AD采集到数据
;**********************************初始入口地址
ORG 0000H
LJMP MAIN
ORG 0003H ;外部中断0
RETI
ORG 000BH ;定时器/计数器0溢出
LJMP TIMER
ORG 0013H ;外部中断1
RETI
ORG 001BH ;定时器/计数器1溢出
RETI
ORG 0023H ;串行囗中断
RETI
ORG 0030H
;*********************************时间中断
TIMER:
PUSH ACC
PUSH PSW
MOV ACC,R1
PUSH ACC
LCALL AD_CONV
POP ACC
MOV R1,ACC
POP PSW
POP ACC
RETI
;---------------------------------------------------------
AD_CONV: ;ADC0832初始化 INT0
MOV A,AD_OPT
ANL A,#00000010B
JZ AD_RET ;A为0说明主程序尚未去走数据则直接返回
MOV A,#00H ;先清0
MOV P0,#0FFH
SETB AD_CS ;一个转换周期开始
CLR AD_CLK
CLR AD_CS ;CS置0,片选有效
SETB AD_DI ;DI置1,起始位
SETB AD_CLK ;第一个脉冲
CLR AD_DI ;在负跳变之前加一个DI反转操作
CLR AD_CLK
SETB AD_DI ;DI置1,设为单通道
SETB AD_CLK ;第二个脉冲
CLR AD_DI ;***
CLR AD_CLK ;
CLR AD_DI ;DI置0,选择通道0
SETB AD_CLK ;第三个脉冲
SETB AD_DI ;***
CLR AD_CLK
NOP
SETB AD_CLK ; 第四个脉冲
MOV R1,#08H ;计数器初值,读取8位数据,
AD_READ: CLR AD_CLK ;下降沿
MOV C,AD_DI ;读取DO端数据
RLC A ;C移入A,高位在前
SETB AD_CLK ;下一个脉冲
DJNZ R1,AD_READ ;没读完继续
SETB AD_CS
MOV AD_DAT,A ;转换结果发给AD_DAT
;以下设置标志位
ORL AD_OPT,#00000001B ;置数据可用位为1
ANL AD_OPT,#11111101B ;置主取位为 0
AD_RET:
RET
;*********************************主程序入口地址
MAIN:
MOV SP,#60H
MOV TMOD,#01H
MOV TH0,#3CH
MOV TL0,#0A0H
SETB EA ;开总中断允许
SETB ET0 ;开定时/计数器0允许
SETB TR0 ;定时/计数器0开始运行
ORL AD_OPT,#00000010B ;置主取位为1
CLR RST
NOP
NOP
SETB RST
CLR LVCC ;打开背景灯
LCALL LCD_INIT
LCALL CLEAR_ALL ;清整个屏幕
;********************************************************以上是软件初始化
HEARE:
MOV R0,#000H
main1: MOV x,R0
LCALL CHECK_USE
mov a,x
anl a,#01000000B
jnz main_r
LCALL LEFT
jmp main2
main_r: LCALL RIGHT
main2: ORL AD_OPT,#00000010B ;置主取位为1
ANL AD_OPT,#11111110B ;置数据可用位为 0
INC R0
CJNE R0, #127,main1
LJMP HEARE
;********************************
LCD_INIT:
MOV COM,#3FH;显示开
LCALL LEFT_COMM ;左半屏写指令子程序
LCALL RIGHT_COMM ;右半屏写指令子程序
;----------------------------------------------------------------------
MOV COM,#0C0H;第一行
LCALL LEFT_COMM ;左半屏写指令子程序
LCALL RIGHT_COMM ;右半屏写指令子程序
;----------------------------------------------------------------------
MOV COM,#0B8H;第一页
LCALL LEFT_COMM ;左半屏写指令子程序
LCALL RIGHT_COMM ;右半屏写指令子程序
;----------------------------------------------------------------------
MOV COM,#40H;第一列
LCALL LEFT_COMM ;左半屏写指令子程序
LCALL RIGHT_COMM ;右半屏写指令子程序
ret
;********************************************************以下是子程序
CHECK_USE:;判断数据是否可用不可用在子程序中循环
PUSH ACC
C_U_TM: MOV A,AD_OPT
ANL A,#00000001B
JZ C_U_TM ;A为0说明数据可用位为0,ad数据不可用,循环测试直到数据可用
POP ACC
RET
CHECK_BUSY: MOV P0,#0FFH ;检测12864液晶屏状态 空闲返回,否则在此子程序中循环
SETB E
MOV A,P0
CLR E
JB ACC.7,CHECK_BUSY
RET
SEND_COMMD: CLR RS ;发送命令到p0口
SETB RW
LCALL CHECK_BUSY
CLR RW
MOV P0,COM
SETB E
NOP
CLR E
RET
SEND_DATE: CLR RS ;发送数据到p0口
SETB RW
LCALL CHECK_BUSY
SETB RS
CLR RW
MOV P0,DAT
SETB E
NOP
CLR E
RET
LEFT_COMM: SETB CS1 ;左半屏写指令子程序
LCALL SEND_COMMD
CLR CS1
RET
LEFT_DATE: SETB CS1 ;左半屏写数据子程序
LCALL SEND_DATE
CLR CS1
RET
RIGHT_COMM: SETB CS2 ;右半屏写指令子程序
LCALL SEND_COMMD
CLR CS2
RET
RIGHT_DATE: SETB CS2 ;右半屏写数据子程序
LCALL SEND_DATE
CLR CS2
RET
LEFT:
MOV A,R0 ;主循环用到了r0
PUSH ACC
MOV R0,#0B8H
L_CLR_QUEUE: MOV COM,R0
LCALL LEFT_COMM
mov a,x
anl a,#00111111B
add a,#01000000B
MOV COM,A
LCALL LEFT_COMM
MOV DAT,#00H
LCALL LEFT_DATE
INC R0
CJNE R0, #0C0H,L_CLR_QUEUE
MOV A,AD_DAT
PUSH ACC
ANL A,#11100000B
SWAP A
RR A
MOV R0,#008H
XCH A,R0
SETB C
SUBB A,R0
MOV R0,#0B8H
ADD A,R0
MOV COM,A
LCALL LEFT_COMM ;左半屏写指令子程序
mov a,x
anl a,#00111111B
add a,#01000000B
MOV COM,A
LCALL LEFT_COMM ;左半屏写指令子程序
POP ACC
ANL A,#00011100b
RR A
RR A
DEC A
MOV R0,A
MOV A,#040H
L_LOOP: RR A
DJNZ R0,L_LOOP
MOV DAT,A
LCALL LEFT_DATE ;左半屏写数据子程序
POP ACC
MOV R0,A
RET
RIGHT: MOV A,R0
PUSH ACC
MOV R0,#0B8H
R_CLR_QUEUE: MOV COM,R0
LCALL RIGHT_COMM
mov a,x
anl a,#00111111B
add a,#01000000B
MOV COM,A
LCALL RIGHT_COMM
MOV DAT,#00H
LCALL RIGHT_DATE
INC R0
CJNE R0, #0C0H,R_CLR_QUEUE
MOV A,AD_DAT
PUSH ACC
ANL A,#11100000B
SWAP A
RR A
MOV R0,#008H
XCH A,R0
SETB C
SUBB A,R0
MOV R0,#0B8H
ADD A,R0
MOV COM,A
LCALL RIGHT_COMM ;左半屏写指令子程序
mov a,x
anl a,#00111111B
add a,#01000000B
MOV COM,A
LCALL RIGHT_COMM ;左半屏写指令子程序
POP ACC
ANL A,#00011100b
RR A
RR A
DEC A
MOV R0,A
MOV A,#040H
R_LOOP: RR A
DJNZ R0,R_LOOP
MOV DAT,A
LCALL RIGHT_DATE ;左半屏写数据子程序
POP ACC
MOV R0,A
RET
CLEAR_ALL: MOV R1,#0B8H ;清显示屏
CLEAR_TMP1: MOV COM,R1
LCALL LEFT_COMM
LCALL RIGHT_COMM
MOV COM,#40H
LCALL LEFT_COMM
LCALL RIGHT_COMM
MOV R0, #64
CLEAR_TMP2: MOV DAT,#00H
LCALL LEFT_DATE
LCALL RIGHT_DATE
DJNZ R0,CLEAR_TMP2
INC R1
CJNE R1, #0C0H,CLEAR_TMP1
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -