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

📄 startup.a51

📁 上位机与多台下位机的单片机多机通信。 做好了通信框架
💻 A51
字号:
/*********************************************
发送缓冲区信息数据结构:
byte	SBB			;send buffer gegin(value:68h)(ram:30h)
byte	SBTA			;send buffer target address(31h)
byte	SBCMD			;send buffer command(32h)
byte	SBDL			;sned buffer data length(33h)
bytes	SBDS			;send buffer datas(ram:34h-3dh)
byte	SBS			;send buffer sum(3eh)
byte	SBE			;send buffer end(value:eeh)(ram:3eh)

接收缓冲区类似,但地址改为40H-4eH
接收状态字 RStatus控制接收到的信息存放位置
Rstatus 00H 初始态,等待接收开始符
Rstatus	01H 等待接收地址
Rstatus	02H 等待接收命令字
Rstatus	03H 等待接收数据长
Rstatus 04H 等待接收数据
Rstatus	05H 等待接收校验和
Rstatus	06H 等待接收结束符

command:
	value:0fh	means:reset slave mcu,not need response
	value:80h	means:match slave mcu,need response
	value:81h	means:permit slave mcu send data
	value:01h	means:package is response info
	value:82h	means:is data package,need response
 
******************************************************/
	SBB	equ	30h
	SBTA	equ	31h		;本机地址	
	SBCMD	equ	32h
	SBDL	equ	33h		;9=>sbdl>=1 34h-3ch存放发送的数据
	SBS	equ	3dh
	SBE	equ	3eh
	addr	equ	3fh		;本机地址
	SBRDY	bit	01h


	RBB	equ	40h
	RBTA	equ	41h		;上位机传送来的地址信息
	RBCMD	equ	42h
	RBDL	equ	43h		;9=>rbdl>=1 44h-4ch存放接收的数据
	RBS	equ	4dh
	RBE	equ	4eh
	Rstatus	equ	4fh
	RBRDY	bit	00h

	org	00h
	ljmp	start
	org	23h
	ljmp	recieve
	org	30h
    start:
    	mov	sp,#5fh
    	anl	pcon,#7fh
	mov	scon,#90h
	setb	ea
	setb	es
	setb	ps
	mov	addr,#01h		;本机地址设置为01h

 



    loop:
	setb	SBRDY			;测试用,假设有数据需要发送
	jnb	RBRDY,$
	clr	RBRDY
	mov	a,#0ffh
	cjne	a,RBTA,no_broadcast
	mov	a,#0fh
	cjne	a,RBCMD,no_reset
	setb	sm2
	ljmp	loop
    no_reset:
    	;广播时候传送给所有slave mcu的指令  扩展用
    	ljmp	loop

    no_broadcast:
    	mov	a,addr
	cjne	a,RBTA,isnot_me
	mov	a,#80h
	cjne	a,RBCMD,no_set
	clr	SM2			;设置sm2=0
	lcall	response		;发送响应帧
	ljmp	loop
    no_set:
    	mov	a,#81h
	cjne	a,RBCMD,no_permit

	mov	SBDL,#04h		;要发送的数据长度 (可以自行设置长度及数据值)
	mov	34h,#55h		;要发送的数据
	mov	35h,#33h		;要发送的数据
	mov	36h,#89h		;要发送的数据
	mov	37h,#56h		;要发送的数据

	lcall	send_data
	ljmp	loop

    no_permit:			;非允许数据发送指令
    	;其他指令 扩展用

    	ljmp	loop
    	

    isnot_me:
	setb	sm2
    	ljmp	loop
    	

	
;;;;;;;;;;;;;;;;;;;;;;
send_data:

	mov	r0,#82h
	mov	r1,SBDL		;SBDL 以及发送数据信息在其他地方设置
	jnb	SBRDY,error		;如果SBRDY不为1则mcu发生错误,SBRDY不为1,不可能进入send_data程序,SBRDY为0断定错误发生
	lcall	write_SB
	lcall	Send
	jnb	RBRDY,$
	mov	a,#01h
	cjne	a,RBCMD,no_response
	clr	SBRDY
	lcall	Clear_sendBuf
	ret
    no_response:			;等待下一次再进行数据传送
    	ret



error:					;出错,则重置
	lcall	Clear_sendBuf
	lcall	Clear_recieveBuf
	clr	RBRDY
	clr	SBRDY
	mov	addr,#01h
	mov	Rstatus,#00h
	ret
	
	
;;;;;;;;;;;;;;;;;;;;;;;;
response:				;发送响应帧
	mov	r0,#01h
	mov	r1,#1h
	mov	34h,#00h
    	jnb	SBRDY,SB_no_RDY
	mov	34h,#01h	
    SB_no_RDY:	
	lcall	write_SB
	lcall	Send
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



write_SB:				;写发送缓冲区
	mov	SBB,#68h
	mov	SBTA,addr
	mov	SBCMD,r0
	mov	SBDL,r1
	mov	a,SBCMD
	add	a,SBDL
	mov	r0,#34h
    add_datas:
	add	a,@r0
	inc	r0
	djnz	r1,add_datas
	mov	SBS,a
	mov	SBE,#55h
	ret



	


	


recieve:		;数据接收,与上位机程序一样



	jbc	TI,is_Send
	clr	RI
	mov	a,#00h
	cjne	a,Rstatus,ignore_begin
	mov	RBB,sbuf
	mov	a,#68h
	cjne	a,RBB,garbage_info
	mov	Rstatus,#01h
	reti
    garbage_info:
    	mov	Rstatus,#00h
	reti
    is_Send:
    	reti
    ignore_begin:
    	mov	a,#01H
	cjne	a,Rstatus,ignore_addr
	mov	RBTA,sbuf
	mov	Rstatus,#02h
	reti
    ignore_addr:
    	mov	a,#02h
	cjne	a,Rstatus,ignore_comm
	mov	RBCMD,sbuf
	mov	Rstatus,#03h
	mov	RBS,RBCMD
	reti
    ignore_comm:
    	mov	a,#03h
	cjne	a,Rstatus,ignore_DLen
	mov	RBDL,sbuf
	mov	r1,RBDL
	mov	r0,#44h
	mov	a,RBS
	add	a,RBDL
	mov	RBS,a
	mov	Rstatus,#04h
	reti
    ignore_DLen:
    	mov	a,#04h
	cjne	a,Rstatus,ignore_Data
	mov	@r0,sbuf
	mov	a,RBS
	add	a,@r0
	mov	RBS,a
	inc	r0
	djnz	r1,continueRD
	mov	Rstatus,#05h
    continueRD:
	reti


    ignore_Data:
    	mov	a,#05h
	cjne	a,Rstatus,ignore_Sum
	mov	a,sbuf
	cjne	a,RBS,recieve_err
	mov	Rstatus,#06h
	reti

    ignore_Sum:
    	mov	a,#06h
	cjne	a,Rstatus,recieve_err
	mov	a,sbuf
	cjne	a,#55h,recieve_err
	mov	RBE,#55h
	mov	Rstatus,#00h
	lcall	recieve_success
	reti

    recieve_err:
    	mov	Rstatus,#00h
	lcall	recieve_error


	reti

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
recieve_success:
	setb	RBRDY
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
recieve_error:
	;扩展用
	ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	



Send:			;数据发送

	mov	sbuf,SBB
	lcall	wait1ms
	mov	sbuf,SBTA
	lcall	wait1ms
	mov	sbuf,SBCMD
	lcall	wait1ms
	mov	sbuf,SBDL
	lcall	wait1ms
	mov	r1,SBDL
	mov	r0,#34h
    send_datas:
	mov	sbuf,@r0
	setb	rs0
	lcall	wait1ms
	clr	rs0
	inc	r0
	djnz	r1,send_datas
    send_sum:
    	mov	sbuf,SBS
	lcall	wait1ms
	mov	sbuf,SBE
	lcall	wait1ms


	ret
/**************************************/


Clear_SendBuf:		;清发送缓冲区



	mov	r0,#30h
	mov	r1,#0fh
    clear_SB:
	mov	@r0,#0h
	inc	r0
	djnz	r1,clear_SB



	ret
/******************************************/

Clear_RecieveBuf:	;清接收缓冲区


	mov	r0,#40h
	mov	r1,#0fh
    clear_RB:
    	mov	@r0,#0h
	inc	r0
	djnz	r1,clear_RB


	ret

/**************************************/
wait1ms:
	
	mov	r0,#25d
    w1msL1:
	mov	b,#20d
	djnz	b,$
	djnz	r0,w1msL1

	ret
/**********************************************/

	end
	

	

⌨️ 快捷键说明

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