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

📄 zsmcu51xpcom.asm

📁 串口通讯实例下位机程序代码配合易语言上位机
💻 ASM
字号:
;=====================================================================================
; 串口实验  PC端软件采用易语言编写
;=====================================================================================
;
;	ZSmcu51XP 学习开发板配套学习例程
;
;	中山单片机学习网	智佳科技
;			
;			作者:逸风
;
;	网站:http://www.zsmcu.com
;	论坛:http://www.zsmcu.net 
;=====================================================================================

PinBEEP	EQU	P2.3
IrPin	EQU	P3.2

SCL	EQU	P2.1
SDA	EQU	P2.0

AddressH	EQU	0AH
AddressL	EQU	0BH


Address	EQU	0EH
I2CData	EQU	0FH

IrDataA	EQU	10H
IrDataB	EQU	11H
IrDataC	EQU	12H
IrDataD	EQU	13H

LED1	EQU	18H
LED2	EQU	19H
LED3	EQU	1AH
LED4	EQU	1BH
LedT0	EQU	1CH

Flag	EQU	20H
	FlagKeyRP	EQU	20H.0	;禁止按键重复执行
OutBuf	EQU	40H
ComBuf	EQU	50H



;=====================================================================================
	ORG	0000H
	JMP	START

;=====================================================================================
	ORG	000BH			;定时器0中断入口
;定时中断主要作显示用
INT_TO:
	PUSH	ACC
	PUSH	PSW

	CLR	TF0		;清定时0中断标?
	MOV	TH0,#0F6H	;2.5MS
	MOV	TL0,#03DH	;

	MOV	A,#11110000B	;关数码管
	ORL	P2,A

	MOV	DPTR,#TABLE
	MOV	A,LedT0
	CJNE	A,#0,INT_T0_1
	MOV	A,LED1
	MOVC	A,@A+DPTR
	MOV	P0,A
	CLR	P2.4	
	MOV	LedT0,#1
	LJMP	INT_T0_END
 INT_T0_1:
  	
	MOV	A,LedT0
	CJNE	A,#1,INT_T0_2
	MOV	A,LED2
	MOVC	A,@A+DPTR
	MOV	P0,A
	CLR	P2.5	
	MOV	LedT0,#2
	LJMP	INT_T0_END
 INT_T0_2:
  	
 	MOV	A,LedT0
	CJNE	A,#2,INT_T0_3
	MOV	A,LED3
	MOVC	A,@A+DPTR
	MOV	P0,A
	CLR	P2.6	
	MOV	LedT0,#3
	LJMP	INT_T0_END
 INT_T0_3:
  	
	MOV	A,LED4
	MOVC	A,@A+DPTR
	MOV	P0,A
	CLR	P2.7	
	MOV	LedT0,#0
	LJMP	INT_T0_END
  	
 INT_T0_END:

	POP	PSW	
	POP	ACC

RETI
TABLE:
	DB	00101000B	;0
	DB	11101011B	;1
	DB	00110010B	;2
	DB	10100010B	;3
	DB	11100001B	;4
	DB	10100100B	;5
	DB	00100100B	;6
	DB	11101010B	;7
	DB	00100000B	;8
	DB	10100000B	;9
	DB	01100000B	;A
	DB	00100101B	;b
	DB	00111100B	;C
	DB	00100011B	;d
	DB	00110100B	;E
	DB	01110100B	;F
	DB	11110111B	;-
	DB	11111111B	;

;=====================================================================================

START:
	CLR	Flag
	mov	sp,#60h

	;===================================================
	;串口初始化
	MOV	SCON,#00H
	MOV	TCON,#00H
	MOV	IE,#00H
	;TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0
	;        0    0   1  0   0    0   0  1
	MOV	TMOD,#00100001b		;T1八位重载,T0十六位定时模式
	MOV	TH1,#0FFH
	MOV	TL1,#0FFH		;波特率28800
	;SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI
	;        0   1   0   1   0   0  0  0
	MOV	SCON,#01010000b
	SETB	TR1
	CLR	RI

	;===================================================
	;定时器中断初始化
;	MOV	TMOD,#01H	;设定T0为十六位定时模式。
	MOV	TH0,#0F6H	;2MS
	MOV	TL0,#03DH	;
	SETB	TR0		;开定时器0
	SETB	ET0		;致能定时0中断
	CLR	TF0		;清定时0中断标志
	SETB	EA			;开总中断

	MOV	LedT0,#00H
	MOV	LED1,#0
	MOV	LED2,#0
	MOV	LED3,#0
	MOV	LED4,#0
;=====================================================================================
MAIN:

;=====================================================================================
;遥控扫描
MAIN_IR:
	JB	IrPin,MAIN_IR_NEXT
	JMP	IR
MAIN_IR_NEXT:

;=====================================================================================
;按键扫描
MAIN_KEY:
	MOV	A,P3
	ORL	A,#00000111B
	CPL	A
	JZ	MAIN_KEY_NO
	CALL	DELAY2400	;延时去抖
	MOV	A,P3
	ORL	A,#00000111B
	CPL	A
	JZ	MAIN_KEY_NO
	;
	JMP	KEY_GOTO
MAIN_KEY_NO:
	CLR	FlagKeyRP
MAIN_KEY_NEXT:
;=====================================================================================
;串口接收
MAIN_RS232_RX:
	JNB	RI,MAIN_RS232_RX_NEXT
	CALL	RS232_Receive
	JNZ	MAIN_RS232_RX_NEXT
	JMP	RS232_GOTO
MAIN_RS232_RX_NEXT:
	
	JMP	MAIN
;=====================================================================================
;遥控处理
IR_GOTO:
	MOV	R0,#OutBuf
	MOV	A,#85		;开始位
	MOV	@R0,A	
	MOV	R0,#OutBuf+1
	MOV	A,#2		;遥控信息
	MOV	@R0,A
	MOV	R0,#OutBuf+2	
	MOV	A,IrDataA
	MOV	@R0,A		;用户码1
	MOV	R0,#OutBuf+3	
	MOV	A,IrDataB
	MOV	@R0,A		;用户码2
	MOV	R0,#OutBuf+4	
	MOV	A,IrDataC
	MOV	@R0,A		;数据码1
	MOV	R0,#OutBuf+5	
	MOV	A,IrDataD
	MOV	@R0,A		;数据码2

	CALL	RS232_SendData	;发送
	JMP	MAIN_IR_NEXT
;=====================================================================================
;遥控处理
KEY_GOTO:
	JB	FlagKeyRP,KEY_GOTO_END
	SETB	FlagKeyRP

	MOV	B,A
	MOV	R0,#OutBuf
	MOV	A,#85		;开始位
	MOV	@R0,A	
	MOV	R0,#OutBuf+1
	MOV	A,#1		;按键信息
	MOV	@R0,A
	MOV	R0,#OutBuf+2	
	MOV	@R0,B		;按键值

	CALL	RS232_SendData	;发送
KEY_GOTO_END:
	JMP	MAIN_KEY_NEXT
;=====================================================================================
RS232_GOTO:
	MOV	R0,#ComBuf
	MOV	A,@R0
	XRL	A,#85
	JNZ	RS232_GOTO_END	;开始码不等于85,则退出

	MOV	R0,#ComBuf+1
	MOV	A,@R0
	CJNE	A,#1,$+6
	LJMP	RS232_GOTO_LED
	CJNE	A,#2,$+6
	LJMP	RS232_GOTO_DIGIT
	CJNE	A,#3,$+6
	LJMP	RS232_GOTO_READ_2402
	CJNE	A,#4,$+6
	LJMP	RS232_GOTO_WRITE_2402
RS232_GOTO_END:
	JMP	MAIN

;================================================================
RS232_GOTO_LED:
	MOV	R0,#ComBuf+2
	MOV	A,@R0	
	CPL	A
	MOV	P1,A

	CALL	BEEP	;响一下
	JMP	MAIN
;================================================================
RS232_GOTO_DIGIT:
	MOV	R0,#ComBuf+2
	MOV	A,@R0
	ANL	A,#00001111B
	MOV	LED1,A
	MOV	R0,#ComBuf+3
	MOV	A,@R0
	ANL	A,#00001111B
	MOV	LED2,A
	MOV	R0,#ComBuf+4
	MOV	A,@R0
	ANL	A,#00001111B
	MOV	LED3,A
	MOV	R0,#ComBuf+5
	MOV	A,@R0
	ANL	A,#00001111B
	MOV	LED4,A

	CALL	BEEP	;响一下
	JMP	MAIN
;================================================================
RS232_GOTO_READ_2402:
	MOV	R0,#ComBuf+2
	MOV	A,@R0
	MOV	Address,A
	CALL	I2C_READ	;读出数据
	JC	RS232_GOTO_READ_2402_END	;读数数失败
	;发送数据
	MOV	B,A
	MOV	R0,#OutBuf
	MOV	A,#85		;开始位
	MOV	@R0,A	
	MOV	R0,#OutBuf+1
	MOV	A,#3		;24C02数据信息
	MOV	@R0,A
	MOV	R0,#OutBuf+2
	MOV	A,Address	
	MOV	@R0,A		;地址
	MOV	R0,#OutBuf+3
	MOV	A,I2CData	
	MOV	@R0,A		;数据

	CALL	RS232_SendData	;发送
	JMP	MAIN
RS232_GOTO_READ_2402_END:
	JMP	MAIN
;================================================================
RS232_GOTO_WRITE_2402:
	MOV	R0,#ComBuf+2
	MOV	A,@R0
	MOV	Address,A
	MOV	R0,#ComBuf+3
	MOV	A,@R0
	MOV	I2CData,A	
	CALL	I2C_WRITE	;读出数据
	JC	RS232_GOTO_WRITE_2402_END	;读数数失败

	CALL	BEEP	;响一下
RS232_GOTO_WRITE_2402_END:
	JMP	MAIN


;=====================================================================================
;	RS232 通讯子程序
;=====================================================================================

;=====================================================================================
;接收数据,6字节
;=====================================================================================
RS232_Receive:
	CLR	RI
	MOV	R0,#ComBuf
	MOV	@R0,SBUF
	MOV	R7,#6
RS232_Receive_LOOP:
	;超时检测
	MOV	R3,#250
    RS232_Receive_DELAY_R3:
	MOV	R4,#250
    RS232_Receive_DELAY_R4:
	JB	RI,RS232_Receive_GO
	DJNZ	R4,RS232_Receive_DELAY_R4
	DJNZ	R3,RS232_Receive_DELAY_R3
	JMP	RS232_Receive_ERROR

    RS232_Receive_GO:
	INC	R0
	MOV	@R0,SBUF
	CLR	RI

	DJNZ	R7,RS232_Receive_LOOP
RS232_Receive_RIGHT:
	SETB	C
	RET
RS232_Receive_ERROR:
	CLR	C
	RET

;=====================================================================================
;发送数据,6字节
;=====================================================================================
RS232_SendData:
	MOV	R0,#OutBuf

	MOV	R7,#6
    RS232_SendData_18BYTE:
	CLR	TI
	MOV	SBUF,@R0
	JNB	TI,$	;等待发送完成
	CLR	TI

	INC	R0
	DJNZ	R7,RS232_SendData_18BYTE
RET


;=====================================================================================
;	AT24C01 处理子程序
;=====================================================================================

/*------------------------------------------------------
写一个字节	Address地址	I2CDatata写入的数据
------------------------------------------------------*/
I2C_WRITE:
	MOV	R6,#30		;等待30MS
    I2C_WRITE_A:
	call	I2C_START
	MOV	A,#10100000B
	call	I2C_SEND8BIT
	call	I2C_ACK
	JNC	I2C_WRITE_A_GO	;=1,表示无确认,再次发送
	CALL	DELAY1000
	DJNZ	R6,I2C_WRITE_A
	JMP	I2C_WRITE_ERROR
    I2C_WRITE_A_GO:
	
	MOV	A,Address
	call	I2C_SEND8BIT
	call	I2C_ACK	

	MOV	A,I2CData
	call	I2C_SEND8BIT
	call	I2C_ACK	
	call	I2C_STOP

	CLR	C
	RET	
I2C_WRITE_ERROR:
	SETB	C
	RET


/*------------------------------------------------------
读一个字节	Address地址	Data读出的数据
------------------------------------------------------*/

I2C_READ:
	MOV	R6,#30		;等待30MS
    I2C_READ_A:
	call	I2C_START
	MOV	A,#10100000B
	call	I2C_SEND8BIT
	call	I2C_ACK
	JNC	I2C_READ_A_GO	;=1,表示无确认,再次发送
	CALL	DELAY1000
	DJNZ	R6,I2C_READ_A
	JMP	I2C_READ_ERROR
    I2C_READ_A_GO:

	MOV	A,Address
	call	I2C_SEND8BIT
	call	I2C_ACK	

	MOV	R6,#30		;等待30MS
    I2C_READ_B:
	call	I2C_START
	MOV	A,#10100001B
	call	I2C_SEND8BIT
	call	I2C_ACK
	JNC	I2C_READ_B_GO	;=1,表示无确认,再次发送
	CALL	DELAY1000
	DJNZ	R6,I2C_READ_B
	JMP	I2C_READ_ERROR
    I2C_READ_B_GO:

	call	I2C_RECEIVE8BIT
	MOV	I2CData,A
	call	I2C_ACK
	call	I2C_STOP

	CLR	C
RET
I2C_READ_ERROR:
	SETB	C
	RET


;发送开始信号
I2C_START:
	SETB	SCL
	SETB	SDA
	NOP
	NOP
	CLR	SDA
	NOP
	NOP
	CLR	SCL
RET
;发送结束信号
I2C_STOP:
	CLR	SDA
	NOP
	NOP
	SETB	SCL
	NOP
	NOP
	SETB	SDA
RET

;发送接收确认信号
I2C_ACk:
	SETB	SDA
	SETB	SCL
	NOP
	NOP
	JB	SDA,I2C_ACK0
	CLR	C	
	SJMP	I2C_ACK_END
    I2C_ACK0:
	SETB	C
    I2C_ACK_END:
	CLR	SCL
RET

;送八位数据
I2C_SEND8BIT:
	MOV	B,#08H
I2C_SEND8BIT_A:	
	RLC	A
	
	MOV	SDA,C
	SETB	SCL
	NOP
	NOP
	CLR	SCL
	DJNZ	B,I2C_SEND8BIT_A
RET


;接收八位数据
I2C_RECEIVE8BIT:
	MOV	B,#08H
	CLR	A
	SETB	SDA
I2C_RECEIVE8IT_A:
	SETB	SCL
	NOP
	NOP
	MOV	C,SDA
	RLC	A
	CLR	SCL
	DJNZ	B,I2C_RECEIVE8IT_A

RET
;=====================================================================================
;	遥控接收子程序
;=====================================================================================

IR: 
	;以下对遥控信号的9000微秒的初始低电平信号的识别,波形见图5。
  	MOV 	R6,#9
IR_SB:
	ACALL 	DELAY882	;调用882微秒延时子程序
	JB	IrPin,IR_ERROR	;延时882微秒后判断P3.2脚是否出现高电平如果有就退出解								;码程序
 	DJNZ 	R6,IR_SB	;重复10次,目的是检测在8820微秒内如果出现高电平就退								;出解码程序

	;识别连发码,和跳过4.5ma的高电平。
	JNB	IrPin, $ 	;等待高电平避开9毫秒低电平引导脉冲
	ACALL	DELAY2400
	JNB	IrPin,IR_Rp	;这里为低电平,认为是连发码信号,见图6。
	ACALL	DELAY2400 	;延时4.74毫秒避开4.5毫秒的结果码

	;以下32数据码的读取 ,0和1的识别 请看图2
	MOV	R1,#IrDataA	;设定IrDataA为起始RAM区
	MOV	R2,#4 
IR_4BYTE: 	
	MOV	R3,#8
IR_8BIT:	
	JNB	IrPin,$		;等待地址码第一位的高电平信号
	LCALL	DELAY882	;高电平开始后用882微秒的时间尺去判断信号此时的高低电								;平状态
	MOV	C,IrPin		;将P3.2引脚此时的电平状态0或1存入C中
	JNC	IR_8BIT_0	;如果为0就跳转到IR_8BIT_0
	LCALL	DELAY1000
IR_8BIT_0: 
	MOV	A,@R1		;将R1中地址的给A
	RRC	A		;将C中的值0或1移入A中的最低位
	MOV	@R1,A		;将A中的数暂时存放在R1中
	DJNZ	R3,IR_8BIT	;接收地址码的高8位
	INC	R1				;对R1中的值加1,换下一个RAM
	DJNZ	R2,IR_4BYTE	;接收完16位地址码和8位数据码和8位数据,
							;存放在1AH/1BH/1CH/1DH的RAM中
	;解码成功
	JMP	IR_GOTO

IR_Rp:
	;这里为重复码执行处
	;按住遥控按键时,每过108ms就到这里来
	LJMP	MAIN ;退出解码子程序
IR_ERROR:
	;错语退出
	LJMP	MAIN ;退出解码子程序



;=============================882
DELAY882: ;1.085x ((202x4)+5)=882
	MOV	R7,#202
    DELAY882_A:
    	NOP
	NOP
	DJNZ	R7,DELAY882_A
RET
;=============================1000
DELAY1000: ;1.085x ((229x4)+5)=999.285
	MOV	R7,#229
    DELAY1000_A:
    	NOP
	NOP
	DJNZ	R7,DELAY1000_A
RET
;=============================2400
DELAY2400: ;1.085x ((245x9)+5)=2397.85
	MOV	R7,#245
    DELAY2400_A:
    	NOP
	NOP
    	NOP
	NOP
	NOP
   	NOP
	NOP
	DJNZ	R7,DELAY2400_A
RET

;=========================================
;接收正确 响一下
BEEP:
	CLR	PinBEEP
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	CALL	DELAY2400
	SETB	PinBEEP
RET
END

⌨️ 快捷键说明

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