📄 pro1.asm
字号:
ORG 0000H
LJMP START
ORG 0003H
LJMP INT0
ORG 000BH
LJMP T0IN
ORG 0023H
LJMP SEVER
ORG 0050H
START: LCALL CHEAKREADY ;判断计算机是否就绪
MOV 64H, #00H
MOV 65H, #00H
AG:
DADD DATA 40H ;数据暂存地址
ADDR DATA 6DH ;AD通道数
DN DATA 6EH ;数据滤波长度
DATALEN1 DATA 73H
DATALEN2 DATA 74H ;存贮数据长度,2为高位
DATASTR1 DATA 00H
DATASTR2 DATA 00H
MOV SP, #30H
SETB ES
SETB EX0
SETB EA
MOV 60H, DATALEN1
MOV 61H, DATALEN2
MOV 62H, #DATASTR1
MOV 63H, #DATASTR2 ;数据存贮器地址
MOV A, DATALEN1
MOV B, ADDR
MUL AB
MOV 7DH, A ;通道1~4数据占的总长度,7D为低字节
MOV 7EH, B
MOV A, DATALEN2
MOV B, ADDR
MUL AB
ADD A, 7EH
MOV 7EH, A ;7E为高字节
AGAIN: LCALL INDATA ;执行采集程序
LCALL COMPUTE ;执行数据滤波程序,并转存数据
LCALL WAIT100mS ;延时100mS再采
MOV R0, 60H
MOV R1, 61H
CJNE R0, #00H, NEXT1
DEC R1
NEXT1: DEC R0
MOV 60H, R0
MOV 61H, R1
CJNE R0, #00H, AGAIN
CJNE R1, #00H, AGAIN ;未完再采
LCALL TRANSFER
SETB ES ;开中断
STAY: MOV A, 79H
CJNE A, #0F0H, AG ;若79H不为F0则继续
CLR ET0 ;否则关T0和外部中断
CLR EX0
SJMP STAY ;等待串口中断
ORG 0200H
INDATA:
MOV DPTR, #0B000H ;选口地址,并指向通道0
MOV R0, #DADD ;数据暂存地址
MOV R7, DN ;数据滤波次数
NEXTT: MOV R6, ADDR ;通道数
MOV A, #00H
READ: MOVX @DPTR, A ;启动转换
LCALL DELAY ;等待转换结束
MOVX A, @DPTR ;读取数据
MOV @R0, A ;存放数据
INC R0 ;存放数据地址加1
INC DPTR ;选择下一个通道
DJNZ R6, READ ;通道未完则继续
MOV DPTR, #0B000H ;完则返回指向通道0
DJNZ R7, NEXTT ;采集次数未达到数据则继续
RET
ORG 0400H
COMPUTE: ;软件滤波,R3为AD后数据地址
;R6为通道数,R7为滤波次数
;通道0计算后放0000H
;通道1计算后放2000H
;通道2计算后放4000H
MOV DPL, 62H
MOV DPH, 63H ;选择数据存储器
MOV R3, #DADD
MOV R7, DN
MOV R6, ADDR ;通道数
NEXTC: MOV A, R3 ;待处理数据地址
MOV R0, A ;计算时的被加数地址
MOV R1, #20H ;计算后数据暂存地址
LCALL SUB ;前两个数相加,程序运行后R0+2*ADDR,R1+1
LCALL SUB ;后两个数相加
MOV A, 20H
MOV R0, #21H
ADD A, @R0 ;再相加
RRC A ;除2
MOVX @DPTR, A ;送至DPTR
INC R3 ;转至下一通道数据
MOV A, DPL
ADD A, DATALEN1
MOV DPL, A
MOV A, DPH
ADD A, DATALEN2 ;指向下一通道存放数据地址
MOV DPH, A
DJNZ R6, NEXTC ;通道未完则继续
INC DPTR ;存储地址加1
CLR C
MOV A, DPL
SUBB A, 7DH ;DPL减00,DPTR变为原来值
MOV DPL, A
MOV A, DPH
SUBB A, 7EH ;DPH减60,变为00
MOV DPH, A
MOV 62H, DPL
MOV 63H, DPH ;DPTR转存62H,63H
RET
SUB: ;除2子程序
MOV A, R0 ;被加数
MOV 7FH, @R0
ADD A, ADDR
MOV R0, A ;加数
MOV A, @R0
ADD A, 7FH
RRC A ;除2
MOV @R1, A ;存至R1
MOV A, R0
ADD A, ADDR ;指向下两个数的首位
MOV R0, A
INC R1 ;存储地址加1
RET
ORG 0600H
CHEAKREADY: ;检察是否与计算机正常通讯
ORL TMOD, #20H ;设定T1为工作方式2
MOV TH1, #0FAH
MOV TL1, #0FAH ;定时器初值,f=6MHZ,N=FC若f=11.0592,N=FA
SETB TR1 ;启动T1工作
MOV PCON, #80H ;置SMOD=1
MOV SCON, #70H ;串口方式1,允许接收
SETB EA ;开CPU中断
CLR ES
SHAKE: MOV SBUF, #0FCH ;主动与计算机建立握手
JNB TI, $
CLR TI
MOV A,#100D
WWW: JB RI, RR2 ;接收计算机返回的数据
DEC A
JZ SHAKE
SJMP WWW
RR2: CLR RI
MOV A, SBUF ;判断是否握手成功
CJNE A, #0FCH, SHAKE ;不成功则重发
SETB ES ;开串口中断
HERE: MOV A,79H ;79H为允许状态,
;单片机可随时查看
;以确定是否停止
CJNE A, #0FEH, HERE ;若不是FE,则中止工作,等待中断
RET
ORG 0800H
TRANSFER:
MOV DPL, #DATASTR1
MOV DPH, #DATASTR2 ;欲发送数据首地址
MOV 75H, ADDR ;通道数
MOV A, DATALEN2
CJNE A, 67H, GOON
GOON: JC LIGHT ;若数据长度高字节<67H,则数字通道满
MOV A, 66H ;若二者相等则比较低字节
CJNE A, DATALEN1, GOON2
GOON2: JC NOLIGHT
LIGHT: INC 75H ;AD通道+光电通道
MOV 64H, #00H
MOV 65H, #00H
NOLight:CLR ES ;关串口中断,以顺序方式发送
MOV SBUF, #0FDH ;发送数据标示
JNB TI, $
CLR TI
MOV SBUF, 75H
JNB TI, $
CLR TI
MOV R3, #00H ;R3为当前发送数据的通道数
NEXTTT: MOV SBUF, R3
JNB TI, $
CLR TI
MOV R0, DATALEN1 ;块长低字节送R0
MOV SBUF, R0 ;发送块长低字节
JNB TI, $
CLR TI
MOV R1, DATALEN2 ;块长高字节送R1
MOV SBUF, R1 ;发送块长高字节
JNB TI, $
CLR TI ;清TI
MOV 76H, #00H ;校验和清0
SDATA: MOVX A, @DPTR ;发送数据字节送A
MOV SBUF, A
ADD A, 76H ;校验和
MOV 76H, A
CJNE R0, #00H, CC1 ;块长(R1,R0)减1
DEC R1
CC1: DEC R0
INC DPTR
JNB TI, $
CLR TI
CJNE R1, #00H, SDATA
CJNE R0, #00H, SDATA ;数据未完,则继续
MOV SBUF, 76H ;数据已完,则发和校验
JNB TI, $
CLR TI
JNB RI, $
CLR RI
MOV A, SBUF
JNZ NEXTTT
INC R3
MOV A, R3
CJNE A, 75H, NEXTTT
SETB ES
RET
ORG 0A00H
SEVER: ;中断服务程序
PUSH A
PUSH PSW
CLR ES ;关中断
JNB RI, RBACK ;若是发送中断,则返回
CLR RI
MOV A, SBUF
CJNE A, #0FFH, TT1 ;若为参数设置则TT1
JNB RI, $ ;若为就绪标志,则接收
CLR RI
MOV A, SBUF
MOV 79H, A ;就绪标志存79H
SJMP RBACK
TT1: CJNE A,#0FCH, TT2 ;若为握手信息,则返回FC
MOV SBUF, A
JNB TI, $
CLR TI
SJMP RBACK
TT2: CJNE A, #0FDH, RBACK ;若不为设置参数标志,则返回
JNB RI, $
CLR RI
MOV A, SBUF
MOV 73H, A ;数据长度低字节放73H
JNB RI, $
CLR RI
MOV A, SBUF
MOV 74H, A ;数据长度高字节放74H
JNB RI, $
CLR RI
MOV A, SBUF
MOV 6EH, A ;滤波长度放6EH
JNB RI, $
CLR RI
MOV A, SBUF
MOV 6FH, A ;延时长度放6FH
JNB RI, $
CLR RI
MOV A, SBUF
MOV 6DH, A ;通道数放6DH
DEC 6DH
RBACK:
SETB ES
POP PSW
POP A
RETI
ORG 0C00H
WAIT100MS: ;延时100ms子程序
PUSH PSW
SETB PSW.3
MOV R7, 6FH ;延时长度由6FH送R7
DL: MOV R6, #250D ;设晶振为6MHz,机器周期为2us
DJNZ R6, $ ;250x4=1000us=1ms
DJNZ R7, DL ;1x100=100ms
POP PSW
RET
DELAY:
PUSH PSW
SETB PSW.4
MOV R7, #40D
DJNZ R7, $ ;40x4=160us
POP PSW
RET
ORG 0D00H
INT0:
PUSH PSW
PUSH DPH
PUSH DPL
PUSH A
MOV A, 65H ;检查数据指针是否为0
JNZ INIT ;
MOV A, 64H
JNZ INIT
MOV A, 7DH ;若为0则重置数据首地址
ADD A, #DATASTR1
MOV 64H, A
MOV A, 7EH
ADDC A, #DATASTR2
MOV 65H, A ;放置通道5数据的首地址
MOV 67H, #00H
MOV 66H, #00H
INIT: ORL TMOD,#01H ;选定时器0,方式1
MOV A, TH0
JZ INT0BACK
MOV A, TL0
JZ INT0BACK
GETDATA:MOV DPL, 64H
MOV DPH, 65H
MOV A, TL0
MOVX @DPTR, A
INC DPTR
MOV A, TH0
MOVX @DPTR, A
INC DPTR
MOV TH0, #00H
MOV TL0, #00H
MOV 65H, DPH
MOV 64H, DPL
MOV DPL, 66H
MOV DPH, 67H
INC DPTR
INC DPTR
MOV 66H, DPL
MOV 67H, DPH
INT0BACK: ;中断返回
SETB ET0
SETB TR0
POP A
POP DPL
POP DPH
POP PSW
RETI
T0IN: ;定时器0中断程序
CLR TF0
ORL TMOD, #01H
MOV TH0, #00H
MOV TL0, #00H
SETB TR0
RETI
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -