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

📄 usb90s23x3.lst

📁 单片机AT90S系列 制作简易USB接口(软件模拟,无usb硬件)。asm源代码
💻 LST
📖 第 1 页 / 共 5 页
字号:
          .equ	ACI	=4
          .equ	ACIE	=3
          .equ	ACIC	=2
          .equ	ACIS1	=1
          .equ	ACIS0	=0
         
          .def	XL	=r26
          .def	XH	=r27
          .def	YL	=r28
          .def	YH	=r29
          .def	ZL	=r30
          .def	ZH	=r31
         
          .equ    RAMEND  =$DF    ;Last On-Chip SRAM Location
          .equ	XRAMEND =$DF
          .equ	E2END	=$7F
          .equ	FLASHEND=$3FF
         
         
          .equ	INT0addr=$001	;External Interrupt0 Vector Address
          .equ	INT1addr=$002	;External Interrupt1 Vector Address
          .equ	ICP1addr=$003	;Input Capture1 Interrupt Vector Address
          .equ	OC1addr =$004	;Output Compare1 Interrupt Vector Address
          .equ	OVF1addr=$005	;Overflow1 Interrupt Vector Address
          .equ	OVF0addr=$006	;Overflow0 Interrupt Vector Address
          .equ	URXCaddr=$007	;UART Receive Complete Interrupt Vector Address
          .equ	UDREaddr=$008	;UART Data Register Empty Interrupt Vector Address
          .equ	UTXCaddr=$009	;UART Transmit Complete Interrupt Vector Address
          .equ	ACIaddr =$00a	;Analog Comparator Interrupt Vector Address
         
         
          .EQU	R4              	=4
          .EQU	inputport			=PINB
          .EQU	outputport			=PORTB
          .EQU	USBdirection		=DDRB
          .EQU	DATAplus			=1				;signal D+ na PB1
          .EQU	DATAminus			=0				;signal D- na PB0 - treba dat na tento pin pull-up 1.5kOhm
          .EQU	USBpinmask			=0b11111100		;mask low 2 bits (D+,D-) on PB
          .EQU	USBpinmaskDplus		=~(1<<DATAplus)	;mask D+ bit on PB
          .EQU	USBpinmaskDminus	=~(1<<DATAminus);mask D- bit on PB
         
          .EQU	TSOPPort			=PINB
          .EQU	TSOPpullupPort		=PORTB
          .EQU	TSOPPin				=2			;signal OUT z IR senzora TSOP1738 na PB2
         
          .EQU	LEDPortLSB			=PORTD		;pripojenie LED diod LSB
          .EQU	LEDPinLSB			=PIND		;pripojenie LED diod LSB (vstup)
          .EQU	LEDdirectionLSB		=DDRD		;vstup/vystup LED LSB
          .EQU	LEDPortMSB			=PORTB		;pripojenie LED diod MSB
          .EQU	LEDPinMSB			=PINB		;pripojenie LED diod MSB  (vstup)
          .EQU	LEDdirectionMSB		=DDRB		;vstup/vystup LED MSB
          .EQU	LEDlsb0				=3		;LED0 na pin PD3
          .EQU	LEDlsb1				=5		;LED1 na pin PD5
          .EQU	LEDlsb2				=6		;LED2 na pin PD6
          .EQU	LEDmsb3				=3		;LED3 na pin PB3
          .EQU	LEDmsb4				=4		;LED4 na pin PB4
          .EQU	LEDmsb5				=5		;LED5 na pin PB5
          .EQU	LEDmsb6				=6		;LED6 na pin PB6
          .EQU	LEDmsb7				=7		;LED7 na pin PB7
         
          .EQU	SOPbyte				=0b10000000	;Start of Packet byte
          .EQU	DATA0PID			=0b11000011	;PID pre DATA0 pole
          .EQU	DATA1PID			=0b01001011	;PID pre DATA1 pole
          .EQU	OUTPID				=0b11100001	;PID pre OUT pole
          .EQU	INPID				=0b01101001	;PID pre IN pole
          .EQU	SOFPID				=0b10100101	;PID pre SOF pole
          .EQU	SETUPPID			=0b00101101	;PID pre SETUP pole
          .EQU	ACKPID				=0b11010010	;PID pre ACK pole
          .EQU	NAKPID				=0b01011010	;PID pre NAK pole
          .EQU	STALLPID			=0b00011110	;PID pre STALL pole
          .EQU	PREPID				=0b00111100	;PID pre PRE pole
         
          .EQU	nSOPbyte		=0b00000001	;Start of Packet byte - opacne poradie
          .EQU	nDATA0PID		=0b11000011	;PID pre DATA0 pole - opacne poradie
          .EQU	nDATA1PID		=0b11010010	;PID pre DATA1 pole - opacne poradie
          .EQU	nOUTPID			=0b10000111	;PID pre OUT pole - opacne poradie
          .EQU	nINPID			=0b10010110	;PID pre IN pole - opacne poradie
          .EQU	nSOFPID			=0b10100101	;PID pre SOF pole - opacne poradie
          .EQU	nSETUPPID		=0b10110100	;PID pre SETUP pole - opacne poradie
          .EQU	nACKPID			=0b01001011	;PID pre ACK pole - opacne poradie
          .EQU	nNAKPID			=0b01011010	;PID pre NAK pole - opacne poradie
          .EQU	nSTALLPID		=0b01111000	;PID pre STALL pole - opacne poradie
          .EQU	nPREPID			=0b00111100	;PID pre PRE pole - opacne poradie
         
          .EQU	nNRZITokenPID	=~0b10000000	;PID maska pre Token paket (IN,OUT,SOF,SETUP) - opacne poradie NRZI
          .EQU	nNRZISOPbyte	=~0b10101011	;Start of Packet byte - opacne poradie NRZI
          .EQU	nNRZIDATA0PID	=~0b11010111	;PID pre DATA0 pole - opacne poradie NRZI
          .EQU	nNRZIDATA1PID	=~0b11001001	;PID pre DATA1 pole - opacne poradie NRZI
          .EQU	nNRZIOUTPID		=~0b10101111	;PID pre OUT pole - opacne poradie NRZI
          .EQU	nNRZIINPID		=~0b10110001	;PID pre IN pole - opacne poradie NRZI
          .EQU	nNRZISOFPID		=~0b10010011	;PID pre SOF pole - opacne poradie NRZI
          .EQU	nNRZISETUPPID	=~0b10001101	;PID pre SETUP pole - opacne poradie NRZI
          .EQU	nNRZIACKPID		=~0b00100111	;PID pre ACK pole - opacne poradie NRZI
          .EQU	nNRZINAKPID		=~0b00111001	;PID pre NAK pole - opacne poradie NRZI
          .EQU	nNRZISTALLPID	=~0b00000111	;PID pre STALL pole - opacne poradie NRZI
          .EQU	nNRZIPREPID		=~0b01111101	;PID pre PRE pole - opacne poradie NRZI
          .EQU	nNRZIADDR0		=~0b01010101	;Adresa = 0 - opacne poradie NRZI
         
         						;stavove byty - State
          .EQU	BaseState		=0		;
          .EQU	SetupState		=1		;
          .EQU	InState			=2		;
          .EQU	OutState		=3		;
          .EQU	SOFState		=4		;
          .EQU	DataState		=5		;
         
         						;Flagy pozadovanej akcie
          .EQU	DoNone						=0
          .EQU	DoReceiveOutData			=1
          .EQU	DoReceiveSetupData			=2
          .EQU	DoPrepareOutContinuousBuffer=3
          .EQU	DoReadySendAnswer			=4
         
         
          .EQU	CRC5poly	=0b00101		;CRC5 polynom
          .EQU	CRC5zvysok	=0b01100		;CRC5 zvysok po uspesnpm CRC5
          .EQU	CRC16poly	=0b1000000000000101	;CRC16 polynom
          .EQU	CRC16zvysok	=0b1000000000001101	;CRC16 zvysok po uspesnom CRC16
         
          .EQU	MAXUSBBYTES				=14			;maximum bytes in USB input message
          .EQU	MAXINFRALENGTH			=36			;maximalna dlzka Infra kodu (pocet jednotiek a nul spolu) (pozor: MAXINFRALENGTH musi byt parne cislo !!!)
          .EQU	NumberOfFirstBits		=10			;kolko prvych bitov moze byt dlhsich
          .EQU	NoFirstBitsTimerOffset	=256-12800*12/1024	;Timeout 12.8ms (12800us) na ukoncenie prijmu po uvodnych bitoch (12Mhz:clock, 1024:timer predivider, 256:timer overflow value)
          .EQU	BaudRate				=12000000/16/57600-1	;nastavit vysielaciu rychlost UART-u na 57600 (pre 12MHz=12000000Hz)
         
          .EQU	InputBufferBegin		=RAMEND-127				;zaciatok prijimacieho shift buffera
          .EQU	InputShiftBufferBegin	=InputBufferBegin+MAXUSBBYTES		;zaciatok prijimacieho buffera
          .EQU	InfraBufferBegin		=InputShiftBufferBegin+MAXUSBBYTES	;zaciatok buffera pre Infra prijem
         
          .EQU	OutputBufferBegin		=RAMEND-MAXUSBBYTES-2	;zaciatok vysielacieho buffera
          .EQU	AckBufferBegin			=OutputBufferBegin-3	;zaciatok vysielacieho buffera Ack
          .EQU	NakBufferBegin			=AckBufferBegin-3	;zaciatok vysielacieho buffera Nak
         
          .EQU	StackBegin		=NakBufferBegin-1	;spodok zasobnika
         
          .DEF	ConfigByte		=R1		;0=unconfigured state
          .DEF	backupbitcount	=R2		;zaloha bitcount registra v INT0 preruseni
          .DEF	RAMread			=R3		;ci sa ma citat zo SRAM-ky
          .DEF	backupSREGTimer	=R4		;zaloha Flag registra v Timer interrupte
          .DEF	backupSREG		=R5		;zaloha Flag registra v INT0 preruseni
          .DEF	ACC				=R6		;accumulator
          .DEF	lastBitstufNumber	=R7		;pozicia bitstuffingu
          .DEF	OutBitStuffNumber	=R8		;kolko bitov sa ma este odvysielat z posledneho bytu - bitstuffing
          .DEF	BitStuffInOut		=R9		;ci sa ma vkladat alebo mazat bitstuffing
          .DEF	TotalBytesToSend	=R10		;kolko sa ma poslat bytov
          .DEF	TransmitPart		=R11		;poradove cislo vysielacej casti
          .DEF	InputBufferLength	=R12		;dlzka pripravena vo vstupnom USB bufferi
          .DEF	OutputBufferLength	=R13		;dlzka odpovede pripravena v USB bufferi
          .DEF	MyUpdatedAddress	=R14		;moja USB adresa na update
          .DEF	MyAddress			=R15		;moja USB adresa
         
         
          .DEF	ActionFlag		=R16		;co sa ma urobit v hlavnej slucke programu
          .DEF	temp3			=R17		;temporary register
          .DEF	temp2			=R18		;temporary register
          .DEF	temp1			=R19		;temporary register
          .DEF	temp0			=R20		;temporary register
          .DEF	bitcount		=R21		;counter of bits in byte
          .DEF	ByteCount		=R22		;pocitadlo maximalneho poctu prijatych bajtov
          .DEF	inputbuf		=R23		;prijimaci register
          .DEF	shiftbuf		=R24		;posuvny prijimaci register
          .DEF	State			=R25		;byte stavu stavoveho stroja
          .DEF	InfraBufptrX	=R26		;XL register - pointer do buffera prijatych IR kodov
          .DEF	InfraBufferFull	=R27		;XH register - priznak plneho Infra Buffera
          .DEF	USBBufptrY		=R28		;YL register - pointer do USB buffera input/output
          .DEF	ROMBufptrZ		=R30		;ZL register - pointer do buffera ROM dat
         
         ;poziadavky na deskriptory
          .EQU	GET_STATUS			=0
          .EQU	CLEAR_FEATURE		=1
          .EQU	SET_FEATURE			=3
          .EQU	SET_ADDRESS			=5
          .EQU	GET_DESCRIPTOR		=6
          .EQU	SET_DESCRIPTOR		=7
          .EQU	GET_CONFIGURATION	=8
          .EQU	SET_CONFIGURATION	=9
          .EQU	GET_INTERFACE		=10
          .EQU	SET_INTERFACE		=11
          .EQU	SYNCH_FRAME			=12
         
         ;typy deskriptorov
          .EQU	DEVICE			=1
          .EQU	CONFIGURATION	=2
          .EQU	STRING			=3
          .EQU	INTERFACE		=4
          .EQU	ENDPOINT		=5
         
         
         ;------------------------------------------------------------------------------------------
         ;********************************************************************
         ;* Interrupt table
         		;; 
         ;********************************************************************.cseg
         ;------------------------------------------------------------------------------------------
          .org 0						;po resete
000000 c051      		rjmp	reset
         ;------------------------------------------------------------------------------------------.org INT0addr					;externe prerusenie INT0
000001 c087      		rjmp	INT0handler
         ;------------------------------------------------------------------------------------------.org INT1addr					;externe prerusenie INT1 (pre AT89S2323 je tu Timer0 prerusenie)
000002 9478      		sei				;povol interrupty na obsluhu USB
000003 b64f      		in		backupSREGTimer,SREG
000004 c003      		rjmp	OVF0handler2323		;na kompatibilitu s AT89S2323 sa skoci na pretecenie casovaca T0
         ;------------------------------------------------------------------------------------------
         ;********************************************************************
         ;* Timer0 interrupt handler
         ;********************************************************************
          .org OVF0addr					;citac/casovac 0
          OVF0handler:
000006 9478      		sei				;povol interrupty na obsluhu USB
000007 b64f      		in		backupSREGTimer,SREG
          OVF0handler2323:
000008 934f      		push	temp0
000009 e040      		ldi		temp0,0<<TOIE0		;zakazat interrupt od casovaca
00000a bf49      		out		TIMSK,temp0
00000b e045      		ldi		temp0,5			;nastav clock input na CLK/1024 = tick kazdych 0.0853ms
00000c bf43      		out		TCCR0,temp0
00000d 933f      		push	temp1
00000e 932f      		push	temp2
00000f 931f      		push	temp3
         
000010 2722      		clr		temp2			;vynulovanie offsetu v bufferi (a flagu pretecenia)
000011 e011      		ldi		temp3,1			;timeout - plnenie citaca (pre prve bity iny ako pre dalsie bity: aby sa nikdy nevyslala dlzka kodu 255, tak sa musi plnit aspon na 1)
          StartTSOPsampling:
000012 e7af      		ldi		InfraBufptrX,InfraBufferBegin+3	;nastavenie sa na zaciatok buffera Infra kodu + 3byty hlavicky (dlzka kodu + counter + offset)
000013 2733      		clr		temp1			;vynulovanie dlzky Infra kodu
          WaitForTOSOP1:
000014 9bb2      		sbis	TSOPPort,TSOPPin	;ak je TSOPPin v nule
000015 c018      		rjmp	CheckWaitForTOSOP1	;tak cakaj na jednotku
000016 c002      		rjmp	StoreToInfraBuffer
          WaitForTOSOP0:
000017 99b2      		sbic	TSOPPort,TSOPPin	;ak je TSOPPin v jednotke
000018 c019      		rjmp	CheckWaitForTOSOP0	;tak cakaj na nulu
          StoreToInfraBuffer:
000019 b742      		in		temp0,TCNT0		;odchyt citac
00001a 1b41      		sub		temp0,temp3		;koriguj odchyteny citac vzhladom na jeho plnenie
00001b 303a      		cpi		temp1,NumberOfFirstBits	;ak este neboli prve bity
00001c f409      		brne	WasNotFirstBits		;tak nechaj plnenie citaca na nule
00001d e61a      		ldi		temp3,NoFirstBitsTimerOffset	;inak zmen plnenie citaca
          WasNotFirstBits:
00001e bf12      		out		TCNT0,temp3		;nastav citac aby bol ako casovac
00001f b94c      		out		UDR,temp0		;vysli data na UART
000020 30b0      		cpi		InfraBufferFull,0	;ak je infra buffer plny
000021 f411      		brne	NoStoreToInfraBuffer	;tak neukladaj data
000022 fe30      		sbrs	RAMread,0		;ak RAMread=1 cita sa z RAM - potom neukladaj data
000023 934d      		st		X+,temp0		;a uloz ho do buffera
          NoStoreToInfraBuffer:
000024 9533      		inc		temp1			;zvys dlzku Infra Buffera
000025 3234      		cpi		temp1,MAXINFRALENGTH	;ak sa nedosiahol maximum Infra buffera
000026 f429      		brne	NoTSOPoverflow		;tak pokracuj
000027 9523      		inc		temp2			;inak si poznac ze pretiekol

⌨️ 快捷键说明

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