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

📄 usbtors232.asm

📁 USB技术大全-54.8M.zip
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		out	DDRD,temp0			;and update direction of data port

		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;--------------------------
DoGetDataPortDirection:
		in	temp0,DDRB			;read direction of DDRB
		sts	AnswerArray,temp0		;to array AnswerArray
		in	temp0,DDRC			;read direction of DDRC
		sts	AnswerArray+1,temp0		;to array AnswerArray
		in	temp0,DDRD			;read direction of DDRD
		sts	AnswerArray+2,temp0		;to array AnswerArray
		ldi	ZL,AnswerArray			;sending is value from AnswerArray
		ldi	temp0,0x81			;RAMREAD=1 - reading from RAM
		mov	RAMread,temp0			;(highest bit set to 1 - to zero RAMread immediatelly)
		ldi	temp0,3				;sending are three bytes
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;--------------------------
DoSetOutDataPort:
		lds	temp1,InputBufferBegin+7	;fourth parameter - bit mask - which port(s) to change

		lds	temp0,InputBufferBegin+4	;first parameter - value of data bits PORTB
		andi	temp0,0b00111100		;mask unused pins
		sbrc	temp1,0				;if bit0 is zero - don't change port state
		out	PORTB,temp0			;and update data port

		lds	temp0,InputBufferBegin+5	;second parameter - value of data bits PORTC
		sbrc	temp1,1				;if bit1 is zero - don't change port state
		out	PORTC,temp0			;and update data port

		lds	temp0,InputBufferBegin+6	;third parameter - value of data bits PORTD
		andi	temp0,0b11111000		;mask unused pins
		ori	temp0,0b00000011		;mask unused pins
		sbrc	temp1,2				;if bit2 is zero - don't change port state
		out	PORTD,temp0			;and update data port

		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;--------------------------
DoGetOutDataPort:
		in	temp0,PORTB			;read PORTB
		sts	AnswerArray,temp0		;to array AnswerArray
		in	temp0,PORTC			;read PORTC
		sts	AnswerArray+1,temp0		;to array AnswerArray
		in	temp0,PORTD			;read PORTD
		sts	AnswerArray+2,temp0		;to array AnswerArray
		ldi	ZL,AnswerArray			;sending is value from AnswerArray
		ldi	temp0,0x81			;RAMREAD=1 - reading from RAM
		mov	RAMread,temp0			;(highest bit set to 1 - to zero RAMread immediatelly)
		ldi	temp0,3				;sending are three bytes
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;--------------------------
DoGetInDataPort:
		in	temp0,PINB			;read PINB
		sts	AnswerArray,temp0		;to array AnswerArray
		in	temp0,PINC			;read PINC
		sts	AnswerArray+1,temp0		;to array AnswerArray
		in	temp0,PIND			;read PIND
		sts	AnswerArray+2,temp0		;to array AnswerArray
		ldi	ZL,AnswerArray			;sending is value from AnswerArray
		ldi	temp0,0x81			;RAMREAD=1 - reading from RAM
		mov	RAMread,temp0			;(highest bit set to 1 - to zero RAMread immediatelly)
		ldi	temp0,3				;sending are three bytes
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;------------------------------------------------------------------------------------------
 DoGetIn:
		ldi	ZL,0				;sending value in R0
		ldi	temp0,0x81			;RAMread=1 - reading from RAM
		mov	RAMread,temp0			;(highest bit set to 1 - to zero RAMread immediatelly)
		ldi	temp0,1				;send only single byte
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;------------------------------------------------------------------------------------------
DoEEPROMRead:
		lds	ZL,InputBufferBegin+4		;first parameter - offset in EEPROM
		lds	ZH,InputBufferBegin+5
		ldi	temp0,2
		mov	RAMread,temp0			;RAMREAD=2 - reading from EEPROM
		ldi	temp0,E2END+1			;number my byte answers to temp0 - entire length of EEPROM
		rjmp	ComposeEndXXXDescriptor		;otherwise prepare data
;--------------------------
DoEEPROMWrite:
		lds	ZL,InputBufferBegin+4		;first parameter - offset in EEPROM (address)
		lds	ZH,InputBufferBegin+5
		lds	R0,InputBufferBegin+6		;second parameter - data to store to EEPROM (data)
		out	EEAR,ZL				;set the address of EEPROM
		out	EEARH,ZH
		out	EEDR,R0				;set the data to EEPROM
		cli					;disable interrupt
		sbi	EECR,EEMWE			;set the master write enable
		sei					;enable interrupt (next instruction is performed)
		sbi	EECR,EEWE			;write
 WaitForEEPROMReady:
		sbic	EECR,EEWE			;wait to the end of write
		rjmp	WaitForEEPROMReady		;in loop (max cca 4ms) (because of possible next reading/writing)
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;--------------------------
DoRS232Send:
		lds	temp0,InputBufferBegin+4	;first parameter - value transmitted to RS232
		out	UDR,temp0			;transmit data to UART
 WaitForRS232Send:
		sbis	UCR,TXEN			;if disabled UART transmitter
		rjmp	OneZeroAnswer			;then finish - protection because loop lock in AT90S2323/2343
		sbis	USR,TXC				;wait for transmition finish
		rjmp	WaitForRS232Send
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;--------------------------
DoRS232Read:
		rjmp	TwoZeroAnswer			;only acknowledge reception with two zero
;--------------------------
DoSetRS232Baud:
		lds	temp0,InputBufferBegin+4	;first parameter - value of baudrate of RS232
		lds	temp1,InputBufferBegin+6	;second parameter - baudrate of RS232 - high byte
		cbr	temp1,1<<URSEL			;writing will be baudrate high byte (no UCSRC)
		out	UBRRH,temp1			;set the speed of UART high byte
		out	UBRR,temp0			;set the speed of UART low byte
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;--------------------------
DoGetRS232Baud:
		in	temp0,UBRR			;return speed of UART Lo
		sts	AnswerArray,temp0
		in	temp0,UBRRH			;return speed of UART Hi
		sts	AnswerArray+1,temp0		;to array AnswerArray
		ldi	ZL,AnswerArray			;sending is value from AnswerArray
		ldi	temp0,0x81			;RAMREAD=1 - reading from RAM
		mov	RAMread,temp0			;(highest bit set to 1 - to zero RAMread immediatelly)
		ldi	temp0,2				;sending are two bytes
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;--------------------------
DoGetRS232Buffer:
		cbi	UCR,RXCIE			;disable interrupt from UART receiving
		nop
		lds	temp0,RS232LengthPosPtr
		lds	temp1,RS232LengthPosPtr+1	;obtain buffer length of RS232 code
		sbi	UCR,RXCIE			;enable interrupt from UART receiving

		cpi	temp0,0				;if this isn't RS232 Buffer empty
		brne	SomeRS232Send			;then send it
		cpi	temp1,0				;if this isn't RS232 Buffer empty
		brne	SomeRS232Send			;then send it
		rjmp	OneZeroAnswer			;otherwise nothing send and acknowledge reception with single zero
 SomeRS232Send:
		lds	ACC,InputBufferBegin+8		;number of requiring bytes to ACC
		ldi	temp2,2				;number of possible bytes (plus word of buffer length)
		add	temp0,temp2
		ldi	temp2,0
		adc	temp1,temp2
		cpi	temp1,0				;if is MSB>0
		brne	AsRequiredGetRS232Buffer	;transmit as many as requested
		cp	ACC,temp0			;if no requested more that I can send
		brcc	NoShortGetRS232Buffer		;transmit as many as requested
 AsRequiredGetRS232Buffer:
		mov	temp0,ACC
		ldi	temp1,0
 NoShortGetRS232Buffer:
		subi	temp0,2				;substract word length
		sbci	temp1,0
		lds	temp2,RS232ReadPosPtr		;obtain index of reading of buffer of RS232 code
		lds	temp3,RS232ReadPosPtr+1
		add	temp2,temp0			;obtain where is end
		adc	temp3,temp1
		cpi	temp3,HIGH(RS232BufferEnd+1)	;if it would overflow
		brlo	ReadNoOverflow			;
		brne	ReadOverflow			;if yes - skip to overflow

		cpi	temp2,LOW(RS232BufferEnd+1)	;otherwise compare LSB
		brlo	ReadNoOverflow			;and do the same
 ReadOverflow:
		subi	temp2,LOW(RS232BufferEnd+1)	;caculate how many not transfered
		sbci	temp3,HIGH(RS232BufferEnd+1)	;caculate how many not transfered
		sub	temp0,temp2			;and with this short length of reading
		sbc	temp1,temp3			;and with this short length of reading
		ldi	temp2,LOW(RS232FIFOBegin)	;and start from zero
		ldi	temp3,HIGH(RS232FIFOBegin)	;and start from zero
 ReadNoOverflow:
		lds	ZL,RS232ReadPosPtr		;obtain index of reading of buffer of RS232 code
		lds	ZH,RS232ReadPosPtr+1		;obtain index of reading of buffer of RS232 code

		sts	RS232ReadPosPtr,temp2		;write new index of reading of buffer of RS232 code
		sts	RS232ReadPosPtr+1,temp3		;write new index of reading of buffer of RS232 code
		sbiw	ZL,2				;space for length data - transmitted as first word

		cbi	UCR,RXCIE			;disable interrupt from UART receiving
		inc	RAMread				;RAMread=1 reading from RAM
		lds	temp2,RS232LengthPosPtr
		lds	temp3,RS232LengthPosPtr+1	;obtain buffer length of RS232 code
		sub	temp2,temp0			;decrement buffer length
		sbc	temp3,temp1
		sts	RS232LengthPosPtr,temp2		;write new buffer length of RS232 code
		sts	RS232LengthPosPtr+1,temp3
		sbi	UCR,RXCIE			;enable interrupt from UART receiving

		st	Z+,temp2			;and save real length to packet
		st	Z,temp3				;and save real length to packet
		sbiw	ZL,1				;and set to begin
		inc	temp0				;and about this word increment number of transmited bytes (buffer length)
		inc	temp0
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;------------------------------------------------------------------------------------------
DoSetRS232DataBits:
		lds	temp0,InputBufferBegin+4	;first parameter - data bits 0=5db, 1=6db, 2=7db, 3=8db
		cpi	temp0,DataBits8			;if to set 8-bits communication
		breq	Databits8or9Set			;then don't change 8/9 bit communication
		in	temp1,UCSRB			;otherwise load UCSRB
		cbr	temp1,(1<<UCSZ2)		;clear 9-bit communication
		out	UCSRB,temp1			;and write back
 Databits8or9Set:
		rcall	RS232DataBitsLocal
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
 RS232DataBitsLocal:
 		rcall	GetUCSRCtotemp1
		bst	temp0,0				;set the UCSZ0
		bld	temp1,UCSZ0
		bst	temp0,1				;set the UCSZ1
		bld	temp1,UCSZ1
		rcall	Settemp1toUCSRC
		ret
 GetUCSRCtotemp1:
		cli					;obtain UCSRC
		in	temp1,UBRRH
		in	temp1,UCSRC			;to temp1
		sei
		nop					;for to enable possible interrupt waiting before ret instruction (ret has long duration)
 		ret
 Settemp1toUCSRC:
		sbr	temp1,(1<<URSEL)		;will be writing to UCSRC
		out	UCSRC,temp1			;and write back to register with new UCSZ0 and UCSZ1
		ret
;------------------------------------------------------------------------------------------
DoGetRS232DataBits:
		rcall	GetUCSRCtotemp1
		clr	temp0				;clear answer
		bst	temp1,UCSZ0			;obtain UCSZ0
		bld	temp0,0				;and save to bit 0
		bst	temp1,UCSZ1			;obtain UCSZ1
		bld	temp0,1				;and save to bit 1
		mov	R0,temp0			;return number of databits in R0
		rjmp	DoGetIn				;and finish
;------------------------------------------------------------------------------------------
DoSetRS232Parity:
		lds	temp0,InputBufferBegin+4	;first parameter - parity: 0=none, 1=odd, 2=even, 3=mark, 4=space
		cpi	temp0,3
		brcc	StableParity
		rcall	GetUCSRCtotemp1
		cbr	temp1,(1<<UPM1)|(1<<UPM0)	;clear parity bits
		cpi	temp0,ParityNone		;if none
		breq	SetParityOut
		sbr	temp1,(1<<UPM1)
		cpi	temp0,ParityEven		;if even
		breq	SetParityOut
		sbr	temp1,(1<<UPM0)
		cpi	temp0,ParityOdd			;if odd
		brne	ParityErrorAnswer
 SetParityOut:
		rcall	Settemp1toUCSRC
		in	temp1,UCSRB			;load UCSRB
		cbr	temp1,(1<<UCSZ2)		;if is 9-bits communication then change it under 9 bits
		out	UCSRB,temp1			;and write back
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
 StableParity:
		in	temp1,UCSRB			;change transmiting parity bit TXB8
		bst	temp0,0				;load lowest bit
		bld	temp1,TXB8			;and save to its place TXB8
		sbr	temp1,(1<<UCSZ2)		;set the UCSZ2 bit - 9 bits communication
		out	UCSRB,temp1			;changed TXB8 and UCSZ2 write to UCSRB

		ldi	temp0,3				;set the 9-databit
		rcall	RS232DataBitsLocal		;and return in temp1 contents UCSRC
		cbr	temp1,(1<<UPM1)|(1<<UPM0)	;disable parity
		rcall	Settemp1toUCSRC
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
 ParityErrorAnswer:
		rjmp	TwoZeroAnswer			;acknowledge reception with two zero
;------------------------------------------------------------------------------------------
DoGetRS232Parity:
		in	temp1,UCSRB			;load UCSRB
		sbrc	temp1,UCSZ2			;if is 9-bits communication
		rjmp	ParityIsStable			;then parity is space or mark

		rcall	GetUCSRCtotemp1
		cbr	temp1,~((1<<UPM0)|(1<<UPM1))	;and let nonzero only parity bits

		cpi	temp1,(1<<UPM0)|(1<<UPM1)	;if are both set
		ldi	temp0,ParityOdd			;this is odd parity
		breq	RetGetParity			;and finish
		cpi	temp1,(1<<UPM1)			;if is UPM1 set
		ldi	temp0,ParityEven		;this is even parity
		breq	RetGetParity			;and finish
		ldi	temp0,ParityNone		;otherwise is that none parity
		rjmp	RetGetParity			;and finish
 ParityIsStable:
		bst	temp1,TXB8			;obtain what is 9-th bit
		ldi	temp0,ParityMark		;prepare mark answer
		brts	RetGetParity			;if is 1 then return mark
		ldi	temp0,ParitySpace		;otherwise return space
 RetGetParity:
 		mov	R0,temp0			;answer move from temp0 to R0
		rjmp	DoGetIn				;and finish
;------------------------------------------------------------------------------------------
DoSetRS232StopBits:
		lds	temp0,InputBufferBegin+4	;first parameter - stop bit 0=1stopbit 1=2stopbits
		rcall	GetUCSRCtotemp1
		bst	temp0,0				;and lowest bit from parameter
		bld	temp1,USBS			;save as stopbit
		rcall	Settemp1toUCSRC
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;------------------------------------------------------------------------------------------
DoGetRS232StopBits:
		rcall	GetUCSRCtotemp1
		clr	R0				;clear answer
		bst	temp1,USBS			;and bit USBS
		bld	R0,0				;write to answer
		rjmp	DoGetIn				;and finish
;----------------------------------------------------------------

⌨️ 快捷键说明

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