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

📄 新建 文本文档.txt

📁 USB 到 UART 协议转换程序 [简易的 - 少量的FIFO] 目标 MCU :AT90S2313-10
💻 TXT
📖 第 1 页 / 共 5 页
字号:
		rjmp	Main

ProcPrepareOutContinuousBuffer:
		rcall	PrepareOutContinuousBuffer	;从缓冲区输出连续数据
		ldi	ActionFlag,DoReadySendAnswer    ;工作标志
		rjmp	Main

ProcReceiveSetupData:   ;接收到配置数据
		ldi	USBBufptrY,InputBufferBegin	;将输入缓冲区用作 USB 输入/输出缓冲区
		mov	ByteCount,InputBufferLength	;接收到的数据长度(设置状态的 DATA 包)
		rcall	DecodeNRZI		;将 NRZI 编码解释为二进制码
		rcall	MirrorInBufferBytes	;镜像输入缓冲区
		rcall	BitStuff		;去掉填充位
		;rcall	CheckCRCIn		;CRC 校验
		rcall	PrepareUSBOutAnswer	;根据配置数据进行进一步的处理
		ldi	ActionFlag,DoReadySendAnswer
		rjmp	Main
;********************************************************************
;* Main program END
;********************************************************************
;------------------------------------------------------------------------------------------
;********************************************************************
;* Interrupt0 interrupt handler
;********************************************************************
INT0Handler:					;prerusenie INT0
		in	backupSREG,SREG         ;INT0 中断中的SREG备份
		push	temp0
		push	temp1

		ldi	temp0,3			;pocitadlo trvania log0
		ldi	temp1,2			;pocitadlo trvania log1
		;测试信号沿,用来达到同步
CheckchangeMinus:
		sbis	inputport,DATAminus	;等待 D- 为 1
		rjmp	CheckchangeMinus
CheckchangePlus:
		sbis	inputport,DATAplus	;等待 D+ 为 1
		rjmp	CheckchangePlus
DetectSOPEnd:   ;同步完成
		sbis	inputport,DATAplus      ;检测数据为1还是为0
		rjmp	Increment0		;D+ =0
Increment1:
		ldi	temp0,3			;加载低电平检测次数(连续3次相同才开始有效数据)
		dec	temp1			;高电平检测
		nop
		breq	USBBeginPacket		;SOP 数据完成,开始数据移位
		rjmp	DetectSOPEnd
Increment0:
		ldi	temp1,2			;加载高电平检测次数(连续2次相同才开始有效数据)
		dec	temp0			;低电平检测
		nop
		brne	DetectSOPEnd		;ak nenastal SOF - pokracuj
		rjmp	EndInt0HandlerPOP2
;
EndInt0Handler: ;结束中断0处理
		pop	ACC
		pop	RS232BufptrX
		pop	temp3
		pop	temp2
EndInt0HandlerPOP: ;结束中断0处理
		pop	USBBufptrY
		pop	ByteCount
		mov	bitcount,backupbitcount	;恢复 bitcount
EndInt0HandlerPOP2: ;结束中断0处理
		pop	temp1
		pop	temp0
		out	SREG,backupSREG         ;恢复 SREG
		ldi	shiftbuf,1<<INTF0	;znulovat flag interruptu INTF0
		out	GIFR,shiftbuf
		reti				;inak skonci (bol iba SOF - kazdu milisekundu)

USBBeginPacket: ;SOP 数据完成,开始数据移位
		mov	backupbitcount,bitcount	;保存 bitcount (在中断返回时恢复)
                ;(读入第0位)
		in	shiftbuf,inputport	;读入 USB 通讯口到移位缓冲区
USBloopBegin:
		push	ByteCount		;保护字节计数
		push	USBBufptrY
		ldi	bitcount,6		;初始化移位计数器
		ldi	ByteCount,MAXUSBBYTES	;初始化到 USB 输入最大的字节数
		ldi	USBBufptrY,InputShiftBufferBegin	;将输入缓冲区用作 USB 输入缓冲区
USBloop1_6:     ;(读入第1-6位)
		in	inputbuf,inputport      ;读入 USB 通讯口到输入缓冲区
		cbr	inputbuf,USBpinmask	;保留 USB 通讯口的2Bit,其余的清0
		breq	USBloopEnd		;是否挂起(同时为0)
		ror	inputbuf		;将D-移到CY中
		rol	shiftbuf                ;将CY中的数据移到移位缓冲区
		dec	bitcount		;移位计数减1
		brne	USBloop1_6		;继续移位
		nop				;inak bude nutne skopirovat shift 寄存器 bo 缓冲区
USBloop7:       ;(读入第7位)
		in	inputbuf,inputport      ;读入 USB 通讯口到输入缓冲区
		cbr	inputbuf,USBpinmask	;保留 USB 通讯口的2Bit,其余的清0
		breq	USBloopEnd		;是否挂起(同时为0,数据中途中断或完成)
		ror	inputbuf		;将D-移到CY中
		rol	shiftbuf                ;将CY中的数据移到移位缓冲区
                ;保存已经接受到的8Bit数据
		ldi	bitcount,7		;初始化 pocitadla bitov v bajte
		st	Y+,shiftbuf		;将移位缓冲区中的数据存入输入缓冲区
USBloop0:	;(读入第0位)
		in	shiftbuf,inputport      ;读入 USB 通讯口到输入缓冲区
		cbr	shiftbuf,USBpinmask	;保留 USB 通讯口的2Bit,其余的清0
		breq	USBloopEnd		;是否挂起(同时为0,数据中途中断或完成)
		dec	bitcount		;移位计数减1
		nop				;
		dec	ByteCount		;移字节计数减1
		brne	USBloop1_6		;将剩下的数据接收完成

		rjmp	EndInt0HandlerPOP	;结束中断0处理

USBloopEnd:     ;挂起(同时为0,数据中途中断或完成)
		cpi	USBBufptrY,InputShiftBufferBegin+3	;接收到的数据是否少于3字节
		brcs	EndInt0HandlerPOP	;少于3字节,结束中断0处理
		lds	temp0,InputShiftBufferBegin+0	;identifikator paketu do temp0
		lds	temp1,InputShiftBufferBegin+1	;adresa do temp1
		brne	TestDataPacket		;接收到的数据大于3字节时,只能是DATA0 a DATA1 包

                ;接收到的数据等于3字节,可能是 SETUP、OUT、IN、DATA0 或 DATA1 包
TestIOPacket:   
;		cp	temp1,MyInAddress	;ak to nie je urcene (adresa) pre mna
;		brne	TestDataPacket		;tak to moze byt este Data Packet
TestSetupPacket:;检测是不是 SETUP 包
		cpi	temp0,nNRZISETUPPID     ;是不是 SETUP 包
		brne	TestOutPacket
		cp	temp1,MyInAddress	;是不是本机地址(IN)  ;ENG;if this isn't assigned (address) for me
		brne	TestDataPacket
		ldi	State,SetupState        ;标记为设置状态
		rjmp	EndInt0HandlerPOP	;结束中断0处理 ak je Setup PID - prijimaj nasledny Data paket
TestOutPacket:	;检测是不是 OUT 包
		cpi	temp0,nNRZIOUTPID       ;是不是 OUT 包
		brne	TestInPacket
		cp	temp1,MyOutAddress	;是不是本机地址(OUT)	;ENG;if this isn't assigned (address) for me
		brne	TestDataPacket
		ldi	State,OutState          ;标记为 OUT 状态
		rjmp	EndInt0HandlerPOP	;结束中断0处理 ak je Out PID - prijimaj nasledny Data paket
TestInPacket:	;检测是不是 IN 包
		cpi	temp0,nNRZIINPID        ;是不是 IN 包
		brne	TestDataPacket
		cp	temp1,MyInAddress	;是不是本机地址(IN)	;ENG;if this isn't assigned (address) for me
		breq	AnswerToInRequest	;tak to moze byt este Data Packet	;ENG;then this can be still DataPacket

TestDataPacket:	;检测是不是 DATA0 或 DATA1 包
		cpi	temp0,nNRZIDATA0PID     ;是不是 DATA0 包
		breq	Data0Packet
		cpi	temp0,nNRZIDATA1PID     ;是不是 DATA1 包
		brne	NoMyPacked		;不是本机能识别的包
Data0Packet:	cpi	State,SetupState	;是不是设置状态的 DATA 包
		breq	ReceiveSetupData
		cpi	State,OutState		;是不是 OUT 状态的 DATA 包
		breq	ReceiveOutData
NoMyPacked:	;不是本机能识别的包(主机只能使用 SETUP 和 OUT 包向终端发送数据)
		ldi	State,BaseState         ;
		rjmp	EndInt0HandlerPOP	;结束中断0处理

AnswerToInRequest:      ;IN 包处理
		push	temp2			;保护数据
		push	temp3
		push	RS232BufptrX
		push	ACC
		cpi	ActionFlag,DoReadySendAnswer	;是否发送已经准备就绪,发送回应
		brne	NoReadySend		;发送 NAK
		rcall	SendPreparedUSBAnswer	;发送准备就绪的回应数据
		cpi	State,AddressChangeState;是否要求改变地址
		breq	SetMyNewUSBAddress	;设置新的本机地址
		ldi	State,InState           ;输入状态
		ldi	ActionFlag,DoPrepareOutContinuousBuffer ;从缓冲区输出连续数据动作标志,主程序中将剩余的数据发送出去
		rjmp	EndInt0Handler		;结束中断0处理

ReceiveSetupData:       ;设置状态的 DATA 包处理
		push	temp2			;保护数据
		push	temp3
		push	RS232BufptrX
		push	ACC
		rcall	SendACK			;响应 SETUP 包,发送 ACK 
		rcall	FinishReceiving		;ukonci prijem
		ldi	ActionFlag,DoReceiveSetupData   ;收到配置数据工作标志,主程序中处理配置数据
		rjmp	EndInt0Handler          ;结束中断0处理

ReceiveOutData:         ;OUT 状态的 DATA 包处理
		push	temp2			;保护数据
		push	temp3
		push	RS232BufptrX
		push	ACC
		cpi	ActionFlag,DoReceiveSetupData	;配置数据工作状态?
		breq	NoReadySend		;发送 NAK
		rcall	SendACK			;发送 ACK
		clr	ActionFlag              ;清除动作标志
		rjmp	EndInt0Handler          ;结束中断0处理
NoReadySend:
		rcall	SendNAK			;发送 NAK
		rjmp	EndInt0Handler		;结束中断0处理
;------------------------------------------------------------------------------------------
SetMyNewUSBAddress:		;设置新的本机地址
		lds	MyInAddress,MyInAddressSRAM
		lds	MyOutAddress,MyOutAddressSRAM
		rjmp	EndInt0Handler          ;结束中断0处理
;------------------------------------------------------------------------------------------
FinishReceiving:		;将接收缓冲区中不满8Bit的数据填满
		cpi	bitcount,7		;prenes do 缓冲区 aj posledny necely byte
		breq	NoRemainingBits		;ak boli vsetky byty prenesene, tak neprenasaj nic
		inc	bitcount
ShiftRemainingBits:
		rol	shiftbuf		;填充数据
		dec	bitcount
		brne	ShiftRemainingBits
		st	Y+,shiftbuf		;将移位缓冲区中的数据存入输入缓冲区
NoRemainingBits:
		mov	ByteCount,USBBufptrY    ;取出输入缓冲区当前指针
		subi	ByteCount,InputShiftBufferBegin-1	;取得接收到的数据量

		mov	InputBufferLength,ByteCount		;保存接收到的数据量
		ldi	USBBufptrY,InputShiftBufferBegin	;指针指向 USB 输入缓冲区首址
		ldi	RS232BufptrX,InputBufferBegin+1		;将输入缓冲区+1用作 RS232 缓冲区
MoveDataBuffer:
		ld	temp0,Y+                                ;将数据移到 RS232 缓冲区
		st	X+,temp0
		dec	ByteCount
		brne	MoveDataBuffer

		ldi	ByteCount,nNRZISOPbyte
		sts	InputBufferBegin,ByteCount		;ako keby sa prijal SOP - nekopiruje sa zo shift 缓冲区
		ret
;------------------------------------------------------------------------------------------
;********************************************************************
;* Other procedures
;********************************************************************
;------------------------------------------------------------------------------------------
USBReset:		;初始化 USB stavoveho stroja
		ldi	temp0,nNRZIADDR0	;初始化 USB adresy
		mov	MyOutAddress,temp0
		mov	MyInAddress,temp0
		clr	State			;初始化 stavoveho stroja
		clr	BitStuffInOut
		clr	OutBitStuffNumber
		clr	ActionFlag
		clr	RAMread			;bude sa vycitavat z ROM-ky
		clr	ConfigByte		;nenakonfiguravany stav
		ret
;------------------------------------------------------------------------------------------
SendPreparedUSBAnswer:	;poslanie kodovanim NRZI OUT buffer s dlzkou OutputBufferLength do USB
		mov	ByteCount,OutputBufferLength		;dlzka odpovede
SendUSBAnswer:	;poslanie kodovanim NRZI OUT buffer do USB
		ldi	USBBufptrY,OutputBufferBegin		;指针 na zaciatok vysielacieho 缓冲区
SendUSBBuffer:	;poslanie kodovanim NRZI dany buffer do USB
		ldi	temp1,0			;zvysovanie pointra (pomocna premenna)
		mov	temp3,ByteCount		;pocitadlo bytov: temp3 = ByteCount
		ldi	temp2,0b00000011	;maska na xorovanie
		ld	inputbuf,Y+		;nacitanie prveho bytu do inputbuf a zvys 指针 do 缓冲区
						;USB ako vystup:
		cbi	outputport,DATAplus	;zhodenie DATAplus : kludovy stav portu USB
		sbi	outputport,DATAminus	;nahodenie DATAminus : kludovy stav portu USB
		sbi	USBdirection,DATAplus	;DATAplus ako vystupny
		sbi	USBdirection,DATAminus	;DATAminus ako vystupny

		in	temp0,outputport	;kludovy stav portu USB do temp0
SendUSBAnswerLoop:
		ldi	bitcount,7		;pocitadlo bitov
SendUSBAnswerByteLoop:
		nop				;oneskorenie kvoli casovaniu
		ror	inputbuf		;do carry vysielany bit (v smere naskor LSB a potom MSB)
		brcs	NoXORSend		;ak je jedna - nemen stav na USB
		eor	temp0,temp2		;inak sa bude stav menit
NoXORSend:
		out	outputport,temp0	;vysli von na USB
		dec	bitcount		;zmensi pocitadlo bitov - podla carry flagu
		brne	SendUSBAnswerByteLoop	;ak pocitadlo bitov nie je nulove - opakuj vysielanie s dalsim bitom
		sbrs	inputbuf,0		;ak je vysielany bit jedna - nemen stav na USB
		eor	temp0,temp2		;inak sa bude stav menit
NoXORSendLSB:
		dec	temp3			;zniz pocitadlo bytov
		ld	inputbuf,Y+		;nacitanie dalsieho bytu a zvys 指针 do 缓冲区
		out	outputport,temp0	;vysli von na USB
		brne	SendUSBAnswerLoop	;opakuj pre cely buffer (pokial temp3=0)

		mov	bitcount,OutBitStuffNumber	;pocitadlo bitov pre bitstuff
		cpi	bitcount,0		;ak nie je potrebny bitstuff
		breq	ZeroBitStuf
SendUSBAnswerBitstuffLoop:
		ror	inputbuf		;do carry vysielany bit (v smere naskor LSB a potom MSB)
		brcs	NoXORBitstuffSend	;ak je jedna - nemen stav na USB
		eor	temp0,temp2		;inak sa bude stav menit
NoXORBitstuffSend:
		out	outputport,temp0	;vysli von na USB
		nop				;oneskorenie kvoli casovaniu
		dec	bitcount		;zmensi pocitadlo bitov - podla carry flagu
		brne	SendUSBAnswerBitstuffLoop	;ak pocitadlo bitov nie je nulove - opakuj vysielanie s dalsim bitom
		ld	inputbuf,Y		;oneskorenie 2 cykly
ZeroBitStuf:
		nop				;oneskorenie 1 cyklus
		cbr	temp0,3
		out	outputport,temp0	;vysli EOP na USB

⌨️ 快捷键说明

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