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

📄 新建 文本文档.txt

📁 USB 到 UART 协议转换程序 [简易的 - 少量的FIFO] 目标 MCU :AT90S2313-10
💻 TXT
📖 第 1 页 / 共 5 页
字号:
		ldi	bitcount,5		;pocitadlo oneskorenia: EOP ma trvat 2 bity (16 cyklov pri 12MHz)
SendUSBWaitEOP:
		dec	bitcount
		brne	SendUSBWaitEOP

		sbi	outputport,DATAminus	;nahodenie DATAminus : kludovy stav na port USB
		sbi	outputport,DATAminus	;oneskorenie 2 cykly: Idle ma trvat 1 bit (8 cyklov pri 12MHz)
		cbi	USBdirection,DATAplus	;DATAplus ako vstupny
		cbi	USBdirection,DATAminus	;DATAminus ako vstupny
		cbi	outputport,DATAminus	;zhodenie DATAminus : treti stav na port USB
		ret
;------------------------------------------------------------------------------------------
ToggleDATAPID:
		lds	temp0,OutputBufferBegin+1	;循环DATA1/DATA0
		cpi	temp0,DATA1PID
		ldi	temp0,DATA0PID
		breq	SendData0PID
		ldi	temp0,DATA1PID
SendData0PID:
		sts	OutputBufferBegin+1,temp0
		ret
;------------------------------------------------------------------------------------------
ComposeZeroDATA1PIDAnswer:
		ldi	temp0,DATA0PID			;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora
		sts	OutputBufferBegin+1,temp0	;nahraj do vyst 缓冲区
ComposeZeroAnswer:
		ldi	temp0,SOPbyte
		sts	OutputBufferBegin+0,temp0	;SOP byte
		rcall	ToggleDATAPID			;zmen DATAPID
		ldi	temp0,0x00
		sts	OutputBufferBegin+2,temp0	;CRC byte
		sts	OutputBufferBegin+3,temp0	;CRC byte
		ldi	ByteCount,2+2			;dlzka vystupneho 缓冲区 (SOP a PID + CRC16)
		ret
;------------------------------------------------------------------------------------------
InitACKBufffer:
		ldi	temp0,SOPbyte
		sts	ACKBufferBegin+0,temp0		;SOP byte
		ldi	temp0,ACKPID
		sts	ACKBufferBegin+1,temp0		;ACKPID byte
		ret
;------------------------------------------------------------------------------------------
SendACK:
		push	USBBufptrY
		push	bitcount
		push	OutBitStuffNumber
		ldi	USBBufptrY,ACKBufferBegin	;指针 na zaciatok ACK 缓冲区
		ldi	ByteCount,2			;pocet vyslanych bytov (iba SOP a ACKPID)
		clr	OutBitStuffNumber
		rcall	SendUSBBuffer
		pop	OutBitStuffNumber
		pop	bitcount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
InitNAKBufffer:
		ldi	temp0,SOPbyte
		sts	NAKBufferBegin+0,temp0		;SOP byte
		ldi	temp0,NAKPID
		sts	NAKBufferBegin+1,temp0		;NAKPID byte
		ret
;------------------------------------------------------------------------------------------
SendNAK:
		push	OutBitStuffNumber
		ldi	USBBufptrY,NAKBufferBegin	;指针 na zaciatok ACK 缓冲区
		ldi	ByteCount,2			;pocet vyslanych bytov (iba SOP a NAKPID)
		clr	OutBitStuffNumber
		rcall	SendUSBBuffer
		pop	OutBitStuffNumber
		ret
;------------------------------------------------------------------------------------------
ComposeSTALL:
		ldi	temp0,SOPbyte
		sts	OutputBufferBegin+0,temp0	;SOP byte
		ldi	temp0,STALLPID
		sts	OutputBufferBegin+1,temp0	;STALLPID byte
		ldi	ByteCount,2			;dlzka vystupneho 缓冲区 (SOP a PID)
		ret
;------------------------------------------------------------------------------------------
DecodeNRZI:	;将 NRZI 编码解释为二进制码
		push	USBBufptrY		;zalohuj 指针 do 缓冲区
		push	ByteCount		;zalohuj dlzku 缓冲区
		add	ByteCount,USBBufptrY	;koniec 缓冲区 do ByteCount
		ser	temp0			;na zabezpecenie jednotkoveho carry (v nasledujucej rotacii)
NRZIloop:
		ror	temp0			;naplnenie carry z predchadzajuceho byte
		ld	temp0,Y			;nahraj prijaty byte z 缓冲区
		mov	temp2,temp0		;posunuty 寄存器 o jeden bit vpravo a XOR na funkciu NRZI dekodovania
		ror	temp2			;carry do najvyssieho bitu a sucasne posuv
		eor	temp2,temp0		;samotne dekodovanie NRZI
		com	temp2			;negovanie
		st	Y+,temp2		;ulozenie spat ako dekodovany byte a zvys 指针 do 缓冲区
		cp	USBBufptrY,ByteCount	;ak este neboli vsetky
		brne	NRZIloop		;tak opakuj
		pop	ByteCount		;obnov dlzku 缓冲区
		pop	USBBufptrY		;obnov 指针 do 缓冲区
		ret				;inak skonci
;------------------------------------------------------------------------------------------
BitStuff:	;odstranenie bit-stuffingu v buffri
		clr	temp3			;pocitadlo vynechanych bitov
		clr	lastBitstufNumber	;0xFF do lastBitstufNumber
		dec	lastBitstufNumber
BitStuffRepeat:
		push	USBBufptrY		;zalohuj 指针 do 缓冲区
		push	ByteCount		;zalohuj dlzku 缓冲区
		mov	temp1,temp3		;pocitadlo vsetkych bitov
		ldi	temp0,8			;spocitat vsetky bity v bufferi
SumAllBits:
		add	temp1,temp0
		dec	ByteCount
		brne	SumAllBits
		ldi	temp2,6			;inicializuj pocitadlo jednotiek
		pop	ByteCount		;obnov dlzku 缓冲区
		push	ByteCount		;zalohuj dlzku 缓冲区
		add	ByteCount,USBBufptrY	;koniec 缓冲区 do ByteCount
		inc	ByteCount		;a pre istotu ho zvys o 2 (kvoli posuvaniu)
		inc	ByteCount
BitStuffLoop:
		ld	temp0,Y			;nahraj prijaty byte z 缓冲区
		ldi	bitcount,8		;pocitadlo bitov v byte
BitStuffByteLoop:
		ror	temp0			;naplnenie carry z LSB
		brcs	IncrementBitstuff	;ak LSB=0
		ldi	temp2,7			;inicializuj pocitadlo jednotiek +1 (ak bola nula)
IncrementBitstuff:
		dec	temp2			;zniz pocitadlo jednotiek (predpoklad jednotkoveho bitu)
		brne	DontShiftBuffer		;ak este nebolo 6 jednotiek za sebou - neposun buffer
		cp	temp1,lastBitstufNumber	;
		ldi	temp2,6			;inicializuj pocitadlo jednotiek (ak by sa nerobil bitstuffing tak sa musi zacat odznova)
		brcc	DontShiftBuffer		;ak sa tu uz robil bitstuffing - neposun buffer

		dec	temp1
		mov	lastBitstufNumber,temp1	;zapamataj si poslednu poziciu bitstuffingu
		cpi	bitcount,1		;aby sa ukazovalo na 7 bit (ktory sa ma vymazat alebo kde sa ma vlozit nula)
		brne	NoBitcountCorrect
		ldi	bitcount,9
		inc	USBBufptrY		;zvys 指针 do 缓冲区
NoBitcountCorrect:
		dec	bitcount
		bst	BitStuffInOut,0
		brts	CorrectOutBuffer	;ak je Out buffer - zvys dlzku 缓冲区
		rcall	ShiftDeleteBuffer	;posun In buffer
		dec	temp3			;zniz pocitadlo vynechani
		rjmp	CorrectBufferEnd
CorrectOutBuffer:
		rcall	ShiftInsertBuffer	;posun Out buffer
		inc	temp3			;zvys pocitadlo vynechani
CorrectBufferEnd:
		pop	ByteCount		;obnov dlzku 缓冲区
		pop	USBBufptrY		;obnov 指针 do 缓冲区
		rjmp	BitStuffRepeat		;a restartni od zaciatku
DontShiftBuffer:
		dec	temp1			;ak uz boli vsetky bity
		breq	EndBitStuff		;ukonci cyklus
		dec	bitcount		;zniz pocitadlo bitov v byte
		brne	BitStuffByteLoop	;ak este neboli vsetky bity v byte - chod na dalsi bit
						;inak nahraj dalsi byte
		inc	USBBufptrY		;zvys 指针 do 缓冲区
		rjmp	BitStuffLoop		;a opakuj
EndBitStuff:
		pop	ByteCount		;obnov dlzku 缓冲区
		pop	USBBufptrY		;obnov 指针 do 缓冲区
		bst	BitStuffInOut,0
		brts	IncrementLength		;ak je Out buffer - zvys dlzku Out 缓冲区
DecrementLength:				;ak je In buffer - zniz dlzku In 缓冲区
		cpi	temp3,0			;bolo aspon jedno znizenie
		breq	NoChangeByteCount	;ak nie - nemen dlzku 缓冲区
		dec	ByteCount		;ak je In buffer - zniz dlzku 缓冲区
		subi	temp3,256-8		;ak nebolo viac ako 8 bitov naviac
		brcc	NoChangeByteCount	;tak skonci
		dec	ByteCount		;inak este zniz dlzku 缓冲区
		ret				;a skonci
IncrementLength:
		mov	OutBitStuffNumber,temp3	;zapamataj si pocet bitov naviac
		subi	temp3,8			;ak nebolo viac ako 8 bitov naviac
		brcs	NoChangeByteCount	;tak skonci
		inc	ByteCount		;inak zvys dlzku 缓冲区
		mov	OutBitStuffNumber,temp3	;a zapamataj si pocet bitov naviac (znizene o 8)
NoChangeByteCount:
		ret				;skonci
;------------------------------------------------------------------------------------------
ShiftInsertBuffer:	;posuv 缓冲区 o jeden bit vpravo od konca az po poziciu: byte-USBBufptrY a bit-bitcount
		mov	temp0,bitcount		;vypocet: bitcount= 9-bitcount
		ldi	bitcount,9
		sub	bitcount,temp0		;do bitcount poloha bitu, ktory treba nulovat

		ld	temp1,Y			;nahraj byte ktory este treba posunut od pozicie bitcount
		rol	temp1			;a posun vlavo cez Carry (prenos z vyssieho byte a LSB do Carry)
		ser	temp2			;FF do masky - temp2
HalfInsertPosuvMask:
		lsl	temp2			;nula do dalsieho spodneho bitu masky
		dec	bitcount		;az pokial sa nedosiahne hranica posuvania v byte
		brne	HalfInsertPosuvMask

		and	temp1,temp2		;odmaskuj aby zostali iba vrchne posunute bity v temp1
		com	temp2			;invertuj masku
		lsr	temp2			;posun masku vpravo - na vlozenie nuloveho bitu
		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount do temp0
		and	temp0,temp2		;odmaskuj aby zostali iba spodne neposunute bity v temp0
		or	temp1,temp0		;a zluc posunutu a neposunutu cast

		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount
		rol	temp0			;a posun ho vlavo cez Carry (aby sa nastavilo spravne Carry pre dalsie prenosy)
		st	Y+,temp1		;a nahraj spat upraveny byte
ShiftInsertBufferLoop:
		cpse	USBBufptrY,ByteCount	;ak nie su vsetky cele byty
		rjmp	NoEndShiftInsertBuffer	;tak pokracuj
		ret				;inak skonci
NoEndShiftInsertBuffer:
		ld	temp1,Y			;nahraj byte
		rol	temp1			;a posun vlavo cez Carry (prenos z nizsieho byte a LSB do Carry)
		st	Y+,temp1		;a nahraj spat
		rjmp	ShiftInsertBufferLoop	;a pokracuj
;------------------------------------------------------------------------------------------
ShiftDeleteBuffer:	;posuv 缓冲区 o jeden bit vlavo od konca az po poziciu: byte-USBBufptrY a bit-bitcount
		mov	temp0,bitcount		;vypocet: bitcount= 9-bitcount
		ldi	bitcount,9
		sub	bitcount,temp0		;do bitcount poloha bitu, ktory este treba posunut
		mov	temp0,USBBufptrY	;uschovanie 指针a do 缓冲区
		inc	temp0			;pozicia celych bytov do temp0
		mov	USBBufptrY,ByteCount	;maximalna pozicia do pointra
ShiftDeleteBufferLoop:
		ld	temp1,-Y		;zniz buffer a nahraj byte
		ror	temp1			;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)
		st	Y,temp1			;a nahraj spat
		cpse	USBBufptrY,temp0	;ak nie su vsetky cele byty
		rjmp	ShiftDeleteBufferLoop	;tak pokracuj

		ld	temp1,-Y		;zniz buffer a nahraj byte ktory este treba posunut od pozicie bitcount
		ror	temp1			;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)
		ser	temp2			;FF do masky - temp2
HalfDeletePosuvMask:
		dec	bitcount		;az pokial sa nedosiahne hranica posuvania v byte
		breq	DoneMask
		lsl	temp2			;nula do dalsieho spodneho bitu masky
		rjmp	HalfDeletePosuvMask
DoneMask:
		and	temp1,temp2		;odmaskuj aby zostali iba vrchne posunute bity v temp1
		com	temp2			;invertuj masku
		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount do temp0
		and	temp0,temp2		;odmaskuj aby zostali iba spodne neposunute bity v temp0
		or	temp1,temp0		;a zluc posunutu a neposunutu cast
		st	Y,temp1			;a nahraj spat
		ret				;a skonci
;------------------------------------------------------------------------------------------
MirrorInBufferBytes:    ;镜像输入缓冲区
		push	USBBufptrY
		push	ByteCount
		ldi	USBBufptrY,InputBufferBegin
		rcall	MirrorBufferBytes
		pop	ByteCount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
MirrorBufferBytes:      ;镜像Y指针指定的缓冲区(Bit7←→BiT0、Bit4←→BiT3)
		add	ByteCount,USBBufptrY	;ByteCount ukazuje na koniec spravy
MirrorBufferloop:
		ld	temp0,Y			;nahraj prijaty byte z 缓冲区
		ldi	temp1,8			;pocitadlo bitov
MirrorBufferByteLoop:
		ror	temp0			;do carry dalsi najnizsi bit
		rol	temp2			;z carry dalsi bit na obratene poradie
		dec	temp1			;bol uz cely byte
		brne	MirrorBufferByteLoop	;ak nie tak opakuj dalsi najnizsi bit
		st	Y+,temp2		;ulozenie spat ako obrateny byte  a zvys 指针 do 缓冲区
		cp	USBBufptrY,ByteCount	;ak este neboli vsetky
		brne	MirrorBufferloop	;tak opakuj
		ret				;inak skonci
;------------------------------------------------------------------------------------------
;CheckCRCIn:
;		push	USBBufptrY
;		push	ByteCount
;		ldi	USBBufptrY,InputBufferBegin
;		rcall	CheckCRC
;		pop	ByteCount
;		pop	USBBufptrY
;		ret
;------------------------------------------------------------------------------------------
AddCRCOut:
		push	USBBufptrY
		push	ByteCount
		ldi	USBBufptrY,OutputBufferBegin
		rcall	CheckCRC
		com	temp0			;negacia CRC
		com	temp1
		st	Y+,temp1		;ulozenie CRC na koniec 缓冲区 (najskor MSB)
		st	Y,temp0			;ulozenie CRC na koniec 缓冲区 (potom LSB)
		dec	USBBufptrY		;指针 na poziciu CRC
		ldi	ByteCount,2		;otocit 2 byty CRC
		rcall	MirrorBufferBytes	;opacne poradie bitov CRC (pri vysielani CRC sa posiela naskor MSB)
		pop	ByteCount
		pop	USBBufptrY

⌨️ 快捷键说明

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