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

📄 int.asm

📁 C51模拟串口及C语言与汇编语言混合使用技术 有很高的参考价值
💻 ASM
字号:

	EXTRN   DATA(snd_len0,snd_chk0,rec_chk0,Sdatabit,Rdatabit,AckAddr) 
	EXTRN	DATA(uart0_status,uart1_status,snd_chk1,rec_chk1,snd_len1,rec_len1)
	EXTRN	DATA(rec_cmd0,rec_cmd1,SBUF1,LAddr)
	EXTRN	BIT(rec_bHead0,isLAddr_bFlg,byte_bFinish,RI2,reclen0_bFlg,recaddr0_bFlg,reccmd0_bFlg,reclen1_bFlg,SM)
	EXTRN	IDATA(SndUart0,RecUart0,SndUart1,RecUart1,Uart0_Over,Uart1_Over,CallTallOver,TmpMs,MsCount)

	    TH2	   DATA	0CDH
	    TL2	   DATA	0CCH
	    T2CON  DATA 0C8H 
	    TR2	   EQU	T2CON.2
	    TF2	   EQU	T2CON.7
	    MS200   EQU	0C8H              ;250ms计时器
	    TH2INIT 	EQU	0FBH	 ;取第2个bit的中点值
	    TL2INIT 	EQU	080H	 ;
	    UART_RXD	EQU	P3.2
	    UART_TXD	EQU	P3.4 
 	    BANK0_REG	EQU	00H  ;选择第0组寄存器
	    BANK1_REG	EQU	08H  ;选择第1组寄存器
	    BANK2_REG	EQU	10H  ;选择第2组寄存器
	    BANK3_REG	EQU	18H  ;选择第3组寄存器
 
        CSEG   AT	0003H
	ORG	0003H
	LJMP	INT0COM_SERVER
	ORG	000BH
	LJMP	T0_SERVER
	ORG	0023H
	LJMP	Uart0_Comm
	ORG	002BH
	LJMP	Uart1_Comm
	ORG	0030H

;串口数据收发   Addr+len+cmd+data0...data3+...+chk
Uart0_Comm:
	PUSH	ACC
	PUSH	PSW
	MOV	PSW,#BANK1_REG
	JB	RI,RECBYTE0
SNDBYTE0:
    CLR	TI
	CJNE	R1,#01H,CSNDDATA0
	;发送完毕
	MOV	uart0_status,#02H        ;02发送完毕
	;接收数据状态
	SETB	P3.6  
	LJMP	ENDCOM00
;发送下一个Byte
CSNDDATA0:
    DEC	R1    ;R1的地址与snd_len0地址相同
	MOV	SBUF,@R0    ;R0 snd0_start
	;发送指针下移一个
	INC	R0
ENDCOM00:
	POP	PSW
	POP	ACC	
	RETI

RECBYTE0:
    CLR	RI
	MOV	A,SBUF
 	JB	rec_bHead0,LABLEN0
	CJNE    A,#0CCH,ENDCOM0   ;头字节
	SETB	rec_bHead0
	SETB	reclen0_bFlg
	SETB    reccmd0_bFlg
	SETB	recaddr0_bFlg          ;准备接收地址
	MOV	rec_chk0,#0CCH
	MOV	uart0_status,#03H    ;03正在接收上级数据
	MOV	R0,#Uart0_Over       ;接收数据记时开始
	MOV	@R0,#0
	LJMP	ENDCOM0
LABLEN0:
    JNB	reclen0_bFlg,LRECCMD
	CLR	reclen0_bFlg
	XRL	rec_chk0,A
	MOV	R0,A                  ;R0表示长度字
	MOV	R1,#RecUart0	      ;R1表示数据存放字
	LJMP	ENDCOM0
 ;接收命令
LRECCMD:
    JNB	reccmd0_bFlg,RECADDR
	MOV	rec_cmd0,A
	XRL	rec_chk0,A
	CLR	reccmd0_bFlg
    DEC	R0                     ;长度减1
	;是否是轮询命令
	CJNE	A,LAddr,ENDCOM0         ;轮询命令
	SETB    isLAddr_bFlg       ;是本机地址
    CLR	    recaddr0_bFlg          
    LJMP	ENDCOM0
;接收第一个地址
RECADDR:
    JNB	    recaddr0_bFlg,LABRDATA0
    CJNE	A,LAddr,NOLAddr
	XRL	    rec_chk0,A
	CLR	    recaddr0_bFlg
	SETB    isLAddr_bFlg       ;是本机地址
	DEC	    R0                    ;长度减1
	LJMP	ENDCOM0
NOLAddr:
	CLR isLAddr_bFlg          ;非本机地址
	POP	PSW
	POP	ACC	
	RETI	
;接收数据
LABRDATA0:
	CJNE	R0,#01H,REC_DATA0
	CLR	    rec_bHead0           ;接收完成
	JNB     isLAddr_bFlg,RecNext ;不是本机命令
	CJNE	A,rec_chk0,CHKERR0
RFINISH0:
	MOV	uart0_status,#04H    ;接收数据完成
	POP	PSW
	POP	ACC	
	RETI
CHKERR0:
    MOV     uart0_status,#05H    ;校验错误
    LJMP	ENDCOM0
RecNext:
	MOV	    uart0_status,#02H        ;接收数据非本机的,状态复位
    LJMP	ENDCOM0
REC_DATA0:
	MOV	@R1,A
	INC	R1
	XRL	rec_chk0,A
	DEC	R0
ENDCOM0:
    POP	PSW
	POP	ACC	
	RETI

;-------------------------------------------
;INT0中断服务程序
INT0COM_SERVER:
       ;等待下一个位的接收时间
	MOV	TH2,#TH2INIT
	MOV	TL2,#TL2INIT
       ;Timer2计时开始
	SETB	TR2
       ;INT0中断标志清除
	CLR	IE0
	MOV	Rdatabit,#09H    ;前面第1位没有收
	CLR	byte_bFinish
       ;INT0关闭
	CLR	EX0 
       ;当前Uart1为接收状态
	SETB	RI2   
	RETI
;T2服务子程序	
Uart1_Comm:
	PUSH	ACC
	PUSH	PSW
	CLR	TF2
	MOV	PSW,#BANK3_REG
	JB	RI2,RECBYTE1
	;发送数据
SndByteBit:       ;发送一个位
	CJNE	R1,#0AH,SETSNDBIT         ;Sdatabit与R1为同一地址变量
       ;发送开始Bit位
	DEC	Sdatabit
       ;数据包长度-第一字节
	DEC	snd_len1               
	CLR	UART_TXD
        POP	PSW
	POP	ACC
	RETI
   
SETSNDBIT:
       ;比较byte是否发完
	CJNE	R1,#00H,SND1BIT
;一个字节发完
SndByte:MOV	A,snd_len1
       ;比较看是否发完了
	JZ	SND1FISH
	;没有发完 发送下一个Byte
	MOV	SBUF1,@R0
	;发送数据指针下移一位
	INC	R0
	;发送完整一贞数据位长度
	MOV	R1,#0AH	  ;10bit
	POP	PSW
	POP	ACC
	RETI
SND1FISH:
       ;一个完整的数据包发送完毕
	MOV	uart1_status,#02H   ;发送数据完毕
	;Timer2停止数据的接收
	CLR	TR2
	;充许INT0中断
	CLR	IE0
	SETB	EX0

	POP	PSW
	POP	ACC
	RETI
SND1BIT:MOV	A,SBUF1
	MOV     C,SM    ;SM在这里用作停止位
	RRC	A
	;保存没有发完的数据
	MOV	SBUF1,A
	;剩下数据位-1
	DEC	Sdatabit
	MOV	UART_TXD,C
        POP	PSW
	POP	ACC
	RETI

RECBYTE1:
       ;没有接收完的BIT个数
	MOV	R0,Rdatabit
	;正在接收的Byte	
	MOV	A,R2   
	CJNE  	R0,#01H,RECBIT0    
        ;一个字节接收完毕,INT0接收设置
	;INT0中断标志清除
	CLR	IE0
	;充许INT0中断
  	SETB	EX0
	;停止Timer2接收数据
  	CLR	TR2
	;SETB	UART_RXD
	;比较是否收到头字节,产生原因是还没有收完最后1bit,提前打开了INT0
       ; JB	byte_bFinish,ENDCOM1
       ;设置 1 Byte接收完成标志
	SETB	byte_bFinish
       ;比较是否是头字节
    CJNE    A,#0CCH,LABLEN1   ;头字节为0CCH
	MOV     R0,rec_len1
	CJNE    R0,#00H,LABLEN1
	MOV	    rec_chk1,A
	SETB	reclen1_bFlg
	LJMP	ENDCOM1
LABLEN1:
	JNB	reclen1_bFlg,LABRDATA1
	CLR	reclen1_bFlg
	MOV	rec_len1,A                  ;rec_len1表示长度字
	XRL	rec_chk1,A
	MOV	R1,#RecUart1	      ;R1表示数据存放字
	LJMP	ENDCOM1
LABRDATA1:
	DEC	 rec_len1
	MOV	 R0,rec_len1
	CJNE R0,#00H,REC_DATA1
    CLR  EX0                   ;关INT0的中断
;接收完成
	CJNE	A,rec_chk1,CHKERR1
    MOV	uart1_status,#03H     ;接收完毕
RFINISH1:
	MOV	R0,#RecUart1
	MOV	rec_cmd1,@R0          ;接收正确
	POP	PSW
	POP	ACC	
	RETI
CHKERR1:
	MOV	uart1_status,#04H     ;校验错误
    LJMP	ENDCOM1
REC_DATA1:
	MOV	@R1,A
	INC	R1
	XRL	rec_chk1,A
ENDCOM1:POP	PSW
	POP	ACC
	RETI

;=================================
;接收一个BIT
RECBIT0:
    MOV C,UART_RXD  
    RRC	A
	MOV	R2,A
 RECENDBIT:
 	DEC	Rdatabit
	POP	PSW
	POP	ACC
	RETI

;==============================						
;------------------------------
;定时器T0   //5MS中断定时  22.1184
T0_SERVER: 
	PUSH	ACC
	PUSH	PSW
	MOV	PSW,#BANK2_REG
	MOV	TH0,#0DCH
	MOV	TL0,#00H
;TmpMs 5MS计时
	MOV	R0,#TmpMs
	MOV	A,@R0
	ADD	A,#1
	MOV	@R0,A
;Com0_Over 5MS计时
	MOV	R0,#Uart0_Over
	MOV	A,@R0
	ADD	A,#1
	MOV	@R0,A
;Com1_Over 5MS计时	
	MOV	R0,#Uart1_Over
	MOV	A,@R0
	ADD	A,#1
	MOV	@R0,A
;1S计时
	MOV	R0,#MsCount
	INC	@R0
	CJNE	@R0,#MS200,ENDCOUNTTIME
	MOV	@R0,#0
	MOV	R0,#CallTallOver
	INC	@R0	

ENDCOUNTTIME:
	POP	PSW
	POP	ACC
	RETI

   END


⌨️ 快捷键说明

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