📄 tst24.asm
字号:
;**************************************************
; 平凡单片机工作室
; http://www.mcustudio.com
; (c) Copyright 2003 Pingfan's McuStudio
; All rights Reserved
;501.asm
;作者:周坚
;功能描述:
;PC端发送3个数据 n0,n1,n2
;n0=0,写,将n1写入n2地址中
;n0=1,读,读出n1地址中的数据,n2不起作用,但必须有
;收到一个字节后,将其值显示在数码管上
;读出一个字节后,将其值显示在数码管上
;用DSB-1A型单片机实验板可提供相应的源程序
;**************************************************
FIRST EQU P2.7 ;第一位数码管的位控制
SECOND EQU P2.6 ;第二位数码管的位控制
DISPBUF EQU 5EH ;5E,5FH是显示缓冲区
REC BIT 00H ;接收到数据的标志
RECBUF EQU 21H ;从21H开始的三个字节是接收缓冲区
COUNT EQU 2FH ;接收缓冲计数器
; 由硬件连线决定的控制线
VSCL BIT p3.6 ; 串行时钟
VSDA BIT p2.5 ; 串行数据
WP BIT P3.7 ;写保护
SLA EQU 50H ;寻址字节存放单元
NUMBYT EQU 51H ;传送字节数存放单元
MTD EQU 52H ;发送数据缓冲区
MRD EQU 52H ;接收数据缓冲区
SLAW EQU 0A0H ;写命令字
SLAR EQU 0A1H ;读命令字
ORG 0
Ljmp MAIN
ORG 23H
Ljmp RECIVE
ORG 30H
MAIN:
mov sp,#5FH
MOV TMOD,#00100000B ;定时器1工作于方式2
MOV TH1,#0FDH ;定时初值
MOV TL1,#0FDH
ORL PCON,#10000000B ;SMOD=1
SETB TR1 ;定时器1开始运行。
MOV SCON,#01000000B ;串口工作方式1
MOV DISPBUF,#0
MOV DISPBUF+1,#0 ;开机显示00
MOV COUNT,#0 ;清接收缓冲计数器
SETB REN ;允许接收
SETB EA
SETB ES
CLR REC ;清接收到数据的标志
MAIN_1:
CALL DISP
JB REC,PROC_REC
jmp MAIN_1
;程序循环\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
PROC_REC:
CLR REC ;清除三个字节标志
mov R0,#RECBUF ;接收缓冲区首地址
mov A,@R0
CJNE A,#0,PROC_REC_1 ;如果接收到的第一个是0,是写片命令
CPL P1.0
inc R0
mov A,@R0
MOV R1,#MTD ;发送数据缓冲区首地址
mov @r1,a ;地址放在发送数据缓冲区的第一位
inc r0
inc r1
mov A,@R0 ;接收到的第三个字节是待写入数据
MOV B,#16
DIV AB
MOV DISPBUF,A
MOV DISPBUF+1,B
MOV A,@R0
mov @r1,a
CLR WP
CLR EA
MOV NUMBYT,#2
MOV SLA,#SLAW ;准备写入数据
call WRNBYT ;掉用写操作
SETB EA
SETB WP
jmp MAIN_1
PROC_REC_1:
CJNE A,#1,MAIN_1 ;如果接收到到的是1,是读命令
CPL P1.1
inc R0
mov A,@R0
mov r1,#MRD
mov @r1,a
MOV SLA,#SLAW
CLR WP
MOV NUMBYT,#1
CALL WRNBYT ;送出地址信号
MOV SLA,#SLAR
MOV NUMBYT,#1
call RDNBYT ;掉用读操作
SETB WP
mov SBUF,A ;送往主机
mov B,#16
div AB
mov DISPBUF,A
mov DISPBUF+1,B
jmp MAIN_1
RECIVE:
push ACC
push PSW
JB RI,REC1 ;如果是接收中断,转
JB TI,REC3 ;如果是发送中断,直接退出
REC1: CLR RI
mov A,#RECBUF
add A,COUNT
mov R0,A
MOV A,SBUF
mov @R0,SBUF ;串口接收数据写入接收缓冲区
MOV B,#16 ;数据送显示缓冲区
DIV AB
MOV DISPBUF,A
MOV DISPBUF+1,B
inc COUNT ;接收缓冲计数器加一
mov A,COUNT ;判断接收计数器是否等于3
CJNE A,#3,REC2
mov COUNT,#0 ;等于3,则清计数器
SETB REC ;已收到3个数据
jmp REC4
REC2: CLR REC
REC3: CLR TI
REC4: POP PSW
pop ACC
RETI
DISP: PUSH ACC ;ACC入栈
PUSH PSW ;PSW入栈
MOV A,DISPBUF ;取第一个待显示数
MOV DPTR,#DISPTAB ;字形表首地址
MOVC A,@A+DPTR ;取字形码
MOV P0,A ;将字形码送P0位(段口)
CLR FIRST ;开第一位显示器位口
LCALL DELAY ;延时5毫秒
SETB FIRST ;关闭第一位显示器(开始准备第二位的数据)
MOV A,DISPBUF+1 ;取显示缓冲区的第二位
MOV DPTR,#DISPTAB
MOVC A,@A+DPTR
MOV P0,A ;将第二个字形码送P0口
CLR SECOND ;开第二位显示器
LCALL DELAY ;延时
SETB SECOND ;关第二位显示
POP PSW
POP ACC
RET
DELAY: PUSH PSW
SETB RS0
MOV R7,#50
D1: MOV R6,#50
D2: DJNZ R6,$
DJNZ R7,D1
POP PSW
RET
DISPTAB: DB 28H,7EH,0a4H,64H,72H,61H,21H,7CH,20H,60H,30H,23H,0A9H,26H,0A1H,0B1H,0FFH
STA: SETB VSDA;启动I2C总线
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSDA
NOP
NOP
NOP
NOP
CLR VSCL
RET
;*********************************************************************************
STOP:
CLR VSDA ;停止I2C总线数据传送
SETB VSCL
NOP
NOP
NOP
NOP
SETB VSDA
NOP
NOP
NOP
NOP
CLR VSDA
CLR VSCL
RET
MACK:
CLR VSDA ;发送应答位
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
SETB VSDA
RET
MNACK:
SETB VSDA ;发送非应答位
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
CLR VSDA
RET
CACK: SETB VSDA ;应答位检查
SETB VSCL
CLR F0
MOV C,VSDA
JNC CEND
SETB F0
CEND: CLR VSCL
RET
WRBYT: MOV R0,#08H ;向VSDA线上发送1个数据字节
WLP: RLC A
JC WR1
AJMP WR0
WLP1: DJNZ R0,WLP
RET
WR1: SETB VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
CLR VSDA
AJMP WLP1
WR0: CLR VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
AJMP WLP1
RDBYT: MOV R0,#08H ;从VSDA线上读取1个数据字节
RLP: SETB VSDA
SETB VSCL
MOV C,VSDA
MOV A,R2
RLC A
MOV R2,A
CLR VSCL
DJNZ R0,RLP
RET
WRNBYT: MOV R3,NUMBYT ;虚拟I2C总线发送N个字节数据
LCALL STA
MOV A,SLA
LCALL WRBYT
LCALL CACK
JB F0,WRNBYT
MOV R1,#MTD
WRDA: MOV A,@R1
LCALL WRBYT
LCALL CACK
JB F0,WRNBYT
INC R1
DJNZ R3,WRDA
LCALL STOP
RET
RDNBYT: MOV R3, NUMBYT ;模拟I2C总线接收n个 ;字节数据
LCALL STA
MOV A,SLA
LCALL WRBYT
LCALL CACK
JB F0,RDNBYT
RDN: MOV R1,#MRD
RDN1: LCALL RDBYT
MOV @R1,A
DJNZ R3,ACK
LCALL MNACK
LCALL STOP
RET
ACK: LCALL MACK
INC R1
SJMP RDN1
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -