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

📄 实验九(点对点串行通信2)_发送.asm

📁 单片机只是别人的东西
💻 ASM
字号:

;功能:在“串入并出”芯片扩展输出引脚基础上,增加串行通信

DISPBUF  DATA    48H     ;笔段码显示缓冲区:
                         ;48H单元记录千位,49H单元记录百位
                         ;4AH单元记录十位,4BH单元记录个位

BTIME    DATA    40H     ;10ms计数单元
SECOND   DATA    4CH     ;秒计数单元
MINUTE   DATA    4DH     ;分计数单元
DISPB    BIT     00H     ;1秒定时时间到标志

TXDBuf   DATA	  30H	 ;发送缓冲区
TXDC     DATA     35H    ;发送/接收字节计数器
TXDOK    BIT      07H    ;发送成功标志(1-成功;0-失败)

SDI     BIT  P1.2 ;串行数据输入
SCLK    BIT  P3.4 ;串行数据移位脉冲
PCLK    BIT  P3.5 ;并行锁存脉冲


ORG 0000H
LJMP MAIN

ORG 0023H
LJMP UART        ;跳串行口中断服务程序入口地址

ORG 002BH
LJMP CTC2               ;定时/计数器T2中断服务程序入口地址

ORG 0050H
;-----主程序开始-----
PROC MAIN
MAIN:
     MOV SP, #0DFH     ;对于具有256字节内部RAM芯片来说,
                       ;将0E0H-0FFH,共计32字节作为堆栈区
     MOV DPTR, #8000H  ;关闭蜂鸣器
     MOV A, #0FFH
     MOVX @DPTR, A

     ;---复位后,将08H-0FF内部RAM单元清0。
     MOV R7, #248
     MOV R0, #08H
LOOP1:
     MOV @R0, #0
     INC R0
     DJNZ R7, LOOP1


     ;----初始化定时器T2
     MOV TH2, #0DCH
     MOV TL2, #00H          ;初值0DC00送定时器T2
     MOV RCAP2H, #0DCH
     MOV RCAP2L, #00H       ;初始化重装初值
     MOV T2CON, #00000100B  ;初始化T2工作方式(自动重装初值、定时)
                            ;并启动了T2

     ;初始化定时器T1(作串行通信波特率发生器输入信号)
     MOV TL1, #250          ;4800波特率对应定时器初值
     MOV TH1, #250
     ANL TMOD, #0F0H
     ORL TMOD, #00100000B   ;定时器T1工作在方式2(8位自动重装初值)
     SETB TR1               ;启动定时器T1
     CLR ET1                ;禁止T1中断

     ;初始化串行口
     MOV SCON, #11010000B   ;串行口工作在方式3,SM2=0,以便用TB8位
                            ;作奇偶校验位。
     ;SETB REN              ;允许接收

     ;-----初始化中断控制器
     SETB PT2               ;将定时器T2中断优先级置为高
     ORL IE, #10110000B
     ;SETB ET2              ;允许定时器T2中断
     ;SETB ES               ;允许串行口中断
     ;SETB EA               ;开中断



     MOV BTIME, #100          ;T2每10ms中断一次,则BTIME回零时间为100*10ms
WAIT:
     JNB DISPB, WAIT
     CLR DISPB                ;清除1秒时间到标志
     LCALL TIMEPROC           ;执行分秒处理及显示子程序
     LCALL S_DISP             ;执行串行输出子程序,将笔段码送LED
     LCALL TIMETXB            ;时间送发送缓冲区,并启动串行发送
     SJMP WAIT                ;等待
END


;定时/计数器T2中断服务程序
PROC CTC2
CTC2:

     DJNZ  BTIME, EXIT ;溢出次数减1,不为0跳转
     ;溢出次数已经回到0,重新初始化溢出次数
     MOV BTIME, #100
     SETB DISPB         ;置位1秒时间到标志
EXIT:
     CLR TF2             ;清除定时器T2溢出标志
     RETI
END

PROC TIMEPROC            ;分秒处理及显示子程序
TIMEPROC:
     ;时间计数单元加+1处理
     INC SECOND          ;秒计数单元+1
     MOV A, SECOND
     CJNE A, #60, NEXT1
NEXT1:
     JC NEXT2
     ;秒大于60,从0开始计数,且分计数单元加1
     MOV SECOND, #0
     INC MINUTE
     MOV A, MINUTE
     CJNE A, #60, NEXT21
NEXT21:
     JC NEXT2          ;分小于60
     MOV SECOND, #0
NEXT2:
     ;秒单元计数器笔段码送显示缓冲区
     MOV A, SECOND
     MOV B, #10
     DIV AB             ;转换为BCD码
                        ;十位在A中,个位在B中
     MOV DPTR, #LEDTAB  ;0-F字模表首地址送DPTR
     MOV R0, #DISPBUF+2
     MOVC A, @A+DPTR    ;查表取笔段码
     MOV @R0, A         ;秒高位笔段码送显示缓冲区

     INC R0             ;指向缓冲区最低位
     MOV A, B           ;取个位码
     MOVC A, @A+DPTR    ;查表取笔段码
     MOV @R0, A         ;秒低位笔段码送显示缓冲区

     ;分单元计数器笔段码送显示缓冲区
     MOV A, MINUTE
     MOV B, #10
     DIV AB             ;转换为BCD码
                        ;十位在A中,个位在B中
     MOV DPTR, #LEDTAB  ;0-F字模表首地址送DPTR
     MOV R0, #DISPBUF
     MOVC A, @A+DPTR    ;查表取笔段码
     MOV @R0, A         ;分高位笔段码送显示缓冲区

     INC R0             ;指向缓冲区最低位
     MOV A, B           ;取个位码
     MOVC A, @A+DPTR    ;查表取笔段码
     CLR ACC.7          ;显示LED202数码管的小数点dp
     MOV @R0, A         ;分低位笔段码送显示缓冲区
     RET
END

PROC S_DISP             ;串行输出子程序
S_DISP:
    MOV R0, #DISPBUF    ;显示缓冲区首地址送R0
    MOV R7, #4
LOOP2:
    MOV A, @R0
    MOV R6, #8
LOOP1:
    CLR SCLK
    RLC A
    MOV SDI, C         ;串行数据送SDI引脚
    SETB SCLK          ;锁存串行输入数据
    DJNZ R6, LOOP1
    ;取下一显示码
    INC R0
    DJNZ R7, LOOP2
    ;4位笔段码已全部移到串入并出芯片中
    CLR PCLK
    NOP                  ;延迟一个机器周期
    SETB PCLK
    RET
END

PROC TIMETXB  ;时间送发送缓冲区
TIMETXB:

     MOV A, SECOND
     MOV B, #10
     DIV AB             ;转换为BCD码
                        ;十位在A中,个位在B中
     MOV R0, #TXDBuf+2
     MOV @R0, A
     INC R0
     MOV @R0, B         ;秒低位送发送缓冲区缓冲区

     ;分单元计数器笔段码送显示缓冲区
     MOV A, MINUTE
     MOV B, #10
     DIV AB             ;转换为BCD码
                        ;十位在A中,个位在B中
     MOV R0, #TXDBuf
     MOV @R0, A
     INC R0
     MOV @R0, B         ;分低位送发送缓冲区缓冲区

     ;计算校验和
     MOV R0, #TXDBuf
     MOV R7, #4
     CLR A              ;清累加器
LOOP1:
     ADD A, @R0         ;累加求和!
     INC R0
     DJNZ R7, LOOP1
     ANL A, #7FH        ;保留和的低7位,避免与帧首标志相同
     MOV @R0, A         ;校验和存入发送缓冲区

     MOV A, #0AAH       ;先发送帧首标志
     MOV C, P           ;奇偶标志P送C
     MOV TB8, C         ;奇偶标志P送TB8,即b8位
     MOV SBUF, A        ;写串行口缓冲寄存器,启动发送
     MOV TXDC, #0       ;初始化发送字节数
     RET
END


PROC UART                  ;串行中断服务子程序
UART:
    PUSH ACC
    PUSH PSW

    SETB RS0               ;切换工作寄存器区
    SETB RS1

    JNB TI, NEXT2
    ;串行发送结束中断
    CLR TI                 ;清除发送结束中断
    ;检查发送字节计数器,确定是否已发送了所有数据
    MOV A, TXDC
    CJNE A, #5, NEXT1
NEXT1:
    JNC NEXT2
    ;小于5,说明尚未完成发送
    ADD A, #TXDBuf           ;加上发送缓冲区首地址
    MOV R0, A
    MOV A, @R0             ;取发送数据
    MOV C, P               ;奇偶标志P送C
    MOV TB8, C             ;奇偶标志P送TB8,即b8位
    MOV SBUF, A            ;写串行口缓冲寄存器,启动发送
    INC TXDC               ;发送字节计数器加1
NEXT2:
    JNB RI, EXIT           ;退出
    CLR RI                 ;清除发送结束中断
    ;串行接收有效
    MOV A, SBUF
    ;执行奇偶校验,P标志与RB8位应该相同,否则就错
    MOV C, P
    ANL C, /RB8            ;计算P. /RB8
    MOV F0, C              ;暂时保存F0标志中
    MOV C, RB8
    ANL C, /P              ;计算RB8. /P
    ORL C, F0              ;完成了P与RB8的异或运算!
    JC EXIT                ;奇偶校验错!
    ;奇偶校验正确!
    CJNE A, #0A5H, NEXT3
    ;等于0A5H,说明接收方已经准确接收,成功标志置1
    SETB TXDOK
    SJMP EXIT
NEXT3:
    CJNE A, #0A6H, EXIT
    ;重新发送
    CLR TXDOK          ;清除发送成功标志
    MOV TXDC, #0       ;初始化发送字节计数器
    MOV A, #0AAH       ;发送帧首标志
    MOV C, P           ;奇偶标志P送C
    MOV TB8, C         ;奇偶标志P送TB8,即b8位
    MOV SBUF, A        ;写串行口缓冲寄存器,启动发送
EXIT:
    POP PSW
    POP ACC
    RETI
END


LEDTAB:                 ;八段LED共阳数码管字模
;数码  0     1     2     3     4     5    6    7
DB     0C0H, 0F9H, 0A4H, 0B0H, 99H, 92H, 82H, 0F8H

;数码  8     9     A     B     C     D     E     F
DB     80H,  90H,  88H, 83H,  0C6H, 0A1H, 86H, 8EH

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -