⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pro1.asm

📁 PC机与单片机的串口通信程序
💻 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 + -