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

📄 tst24.asm

📁 Small RTOS51是为51系列单片机而编写的。它是完全免费的、源代码公开的多任务实时操作系统。它可在无任何外部数据存储器的单片80C51系统上运行
💻 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 + -