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

📄 usb232.asm

📁 用CY7C630芯片做USB转串口的汇编原程序,里面有编译生成的hex文件.写入芯片就可使用.最高波特率为24
💻 ASM
📖 第 1 页 / 共 3 页
字号:

  include "63000.inc"
;Received data:
Data_Byte0:               equ  38h

;Other variables:
suspend_counter:          equ  35h          ;number of idle bus milliseconds 
loop_temp:                equ  37h          ;temporary loop variable
start_send:               equ  32h          ;0=false, 1=true

interrupt_mask:           equ  20h

endp0_data_toggle:        equ  24h
loop_counter:             equ  25h
data_start:               equ  26h
data_count:               equ  27h
endpoint_stall:           equ  28h
data_send:              equ  	28h            ; start of data to be sent
hi_data_count:          equ  	60h            ; high byte of data count
low_data_count:         equ  	61h            ; low byte of data count
loop_num:               equ  	62h            ; loop number (USB sending)
temp2:                  equ  	63h            ; temporary variable
send_ptr:               equ  	7Dh            ; Send buffer ptr       

;======================================================================
;interrupt vectors
;======================================================================

org  00h                ; Reset vector; begin here after a reset.
jmp  Reset

org  02h                ; 128-microsecond interrupt
jmp  Serial_ISR

org  04h                ; 1024-millisecond interrupt 
jmp  One_mSec_ISR

org  06h                ; endpoint 0 interrupt 
jmp  USB_EP0_ISR

org  08h                ; endpoint 1 interrupt 
jmp  USB_EP1_ISR

org  0Ah                ; reserved interrupt 
jmp  Reset

org  0Ch                ; general purpose I/O interrupt 
jmp  GPIO_ISR           ; not used

org  0Eh                ; Wakeup_ISR or resume interrupt 
jmp  DoNothing_ISR      ; not used

ORG  10h

;======================================================================
;Interrupt routines
;======================================================================

;----------------------------------------------------------------------
; 128-microsecond interrupt, Cext
; Unused. If this interrupt occurs, just re-enable the interrupts.
;----------------------------------------------------------------------
DoNothing_ISR:
     push A
     ;Enable interrupts and return
     mov A,[interrupt_mask]
     ipret Global_Interrupt

;----------------------------------------------------------------------
; 1-millisecond interrupt
; Check to see if the chip is in suspend mode.
; Copy values to Endpoint 1's buffer for sending.
;----------------------------------------------------------------------

One_mSec_ISR:
     push A
;This watchdog reset is here until I figure out
;where else in the code the watchdog is timing out!
     iowr Watchdog
;Find out if enumeration is complete.
;If enumerating is in progress, loop_temp = 0.
     mov A, [loop_temp]
     cmp A, 0h
;If enumeration is still in progress, jump.
     jz not_main
;Enumeration has ended, so decrement the loop counter
;(so it no longer = 0).

     dec [loop_temp]

not_main:                         
;Check for bus activity.
     iord USB_Status_Control
     and A, 01h
     cmp A,0h
;If no bus activity, increment the suspend counter.
     jz Inc_counter
;If bus activity detected, clear the bus-activity bit,
     iord USB_Status_Control
     and A, 0FEh
     iowr USB_Status_Control
;and clear the suspend counter.
     mov A, 0h
     mov [suspend_counter], A
     jmp Suspend_end   
Inc_counter:
;Keep track of the amount of time with no bus activity.
     inc [suspend_counter]
;Get the number of milliseconds the bus has been idle.
     mov A, [suspend_counter]
;Has it been 3 milliseconds?
     cmp A, 03h
;If no, there's nothing else to do.
     jnz Suspend_end
;If yes, put the chip in Suspend mode.
;Clear the Suspend counter.
     mov A, 0h
     mov [suspend_counter], A

;Set the Suspend bit. The chip is now in Suspend mode.
     iord Status_Control
     or A, 08h
     iowr Status_Control
     nop

Suspend_end:
;Is endpoint 1 enabled?
     iord USB_EP1_TX_Config
     cmp A,0
;If no, do nothing.
     jz Select
;If yes, is start_send = 1?
;(Start_send adds a short delay after enumeration.)
     mov A, [start_send]
     cmp A, 01h
;If no, do nothing
     jnz Select
;If yes, send data:
     jmp send_value

send_value:
;Copies values from RAM into Endpoint 1's buffer
;and enables sending the bytes on the next poll.

;disable Endpoint 1 interrupts
     mov A,[interrupt_mask]
     and A, EFh
     mov [interrupt_mask],A
     iowr Global_Interrupt

;Copy values from RAM to Endpoint 1's FIFO for transmitting to the host.
;One byte:

     mov A, [Data_Byte0]
     mov [Endpoint1_Byte0], A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Configure Endpoint 1's transmit register 
;so that the bytes will transmit on the next poll.
     iord USB_EP1_TX_Config
;Don't change the Data 0/1 bit.
     and A,40h
;Bits 4 and 7 enable transmitting.
;The low nibble is the number of data bytes (2).
     or A,91h
     iowr USB_EP1_TX_Config

Select:
;Enable Endpoint 1 interrupts.
     mov A,[interrupt_mask]
     or A, 10h
     mov [interrupt_mask],A
     ipret Global_Interrupt



      include  "rs232.asm"

Reset:
;Place the data stack pointer at the lowest address of Endpoint 0's FIFO.
;This keeps the stack from writing over the USB FIFOs.
;The USB FIFOs are in high RAM;
;the data stack pointer pre-decrements on a Push instruction.

     mov A, Endpoint_0
     swap A, dsp

;Initialize variables to FFh
     mov  a,00h
     iowr Port0_Data                 ; output ones to port 0

     mov A, ffh
     iowr Port1_Pullup               ; disable port 1 pullups
                                     ; select rising edge interrupts
     iowr Port1_Isink0               ; maximum isink current Port1 bit 0
     iowr Port1_Isink1               ; maximum isink current Port1 bit 1
     iowr Port1_Isink2               ; maximum isink current Port1 bit 2
     iowr Port1_Isink3               ; maximum isink current Port1 bit 3
     iowr Port0_Isink0               ; maximum sink current Port0 bit 0
     iowr Port0_Isink1               ; maximum sink current Port0 bit 1
     iowr Port0_Isink2               ; maximum sink current Port0 bit 2
     iowr Port0_Isink3               ; maximum sink current Port0 bit 3
     iowr Port0_Isink4               ; maximum sink current Port0 bit 4
     iowr Port0_Isink5               ; maximum sink current Port0 bit 5
     iowr Port0_Isink6               ; maximum sink current Port0 bit 6
     iowr Port0_Isink7               ; maximum sink current Port0 bit 7


;Initialize variables to 00h
     mov A, 0h
     iowr Port1_Data                 ; output zeros to port 1
     iowr Port0_Interrupt            ; disable port 0 interrupts
     iowr Port0_Pullup               ; enable port 0 pullups
    
     mov [Endpoint1_Byte0],A
     mov [Endpoint1_Byte1],A
     mov [Endpoint1_Byte2],A
     mov [endpoint_stall], A
     mov [remote_wakeup_status], A
     mov [configuration_status], A
     mov [loop_temp], A
     mov [start_send], A
     iowr Watchdog                   ; clear watchdog timer

;Test what kind of reset occurred: bus or watchdog
     iord Status_Control
;Was it a bus reset?
     and A, USBReset
;If yes, jump to handle it.
     jnz BusReset
     iord Status_Control
;Was it a watchdog reset?
     and A, WatchDogReset
;If no, continue to wait for a bus reset
     jz suspendReset

     mov A, TIMER_ONLY
     mov [interrupt_mask],A
     iowr Global_Interrupt
;Wait for a bus reset.
WatchdogHandler:
     jmp WatchdogHandler
suspendReset:
;Return to suspend mode to wait for a USB bus reset.
     mov A, 09h
     iowr Status_Control
     nop
     jmp suspendReset

BusReset:
;Clear all reset bits.
;Set bit 0 (the run bit).
     mov A, RunBit
     iowr Status_Control
;Set up for enumeration (Endpoint 0 and 1-millisecond interrupts enabled)
     mov A, ENUMERATE_MASK
     mov [interrupt_mask],A
     iowr Global_Interrupt

wait:
;Wait until configured.
     iord USB_EP1_TX_Config
     cmp A, 0
;Clear the watchdog timer
     iowr Watchdog
;If not configured, continue to wait.
     jz wait

     mov A, 0ffh
     mov [loop_temp], A

;Enable endpoint 1
     iord USB_EP1_TX_Config
     or A, 91h
     iowr USB_EP1_TX_Config

;======================================================================
; The main program loop.
;======================================================================

main:
;Find out if the loop_temp delay has timed out.
;Loop_temp =0 if not timed out, FFh if timed out.
     mov A, [loop_temp]
     cmp A, 0Ah
;If no, don't enable transmitting.
     jnc no_set
;If yes, enable transmitting.
     mov A, 01h
     mov [start_send],A

no_set:
;Clear the watchdog timer (accumulator=0)
;This has to be done at least once every 3 milliseconds!
;************************************************************************
; This is the main loop that is entered after reset processing
;************************************************************************

;main:
       call SerialInitialize
       iowr    Watchdog                ; clear watchdog timer	
       call put_String
       call putCommand
       call delay1
;      call getSerial
;    iowr Watchdog
 nochange:
     jmp main


put_String:
        push    A                       ; Save the accumulator.
        push    X                       ; Save the index register.
        call  initialize_req
        mov   A,[Data_Byte0]               ; Load ASCII 'I' into accumulator
        mov   [X + txBuf], A            ; Write into the buffer.
        pop   X                         ; Restore the index.
        pop   A                       ; Restore the accumulator.
        ret                             ; Return to caller.

;*******************************************************************
; This routine initializes the sending of requests to the UPS
;*******************************************************************
initialize_req:
        call    delay                   
        call    Clear_rxBuf
        mov     A, 00h          ;
        mov     [rxBufPtr], A   ; Reset the receive buffer pointer.
        mov     [txBufPtr], A   ;
        mov     X, [txBufPtr]   ;
        ret

;************************************************************************
; This routine ends the transmission loading part, transmits the commands
; and receives the result from the UPS
;************************************************************************
end_req:
        mov   [X + txBuf], A    
        inc   [txBufPtr]           ; Increment tx buffer pointer
        mov   X, [txBufPtr]   
        mov   A, Car_Ret           ; Load carriage return into accumulator
        mov   [X + txBuf], A    
        inc   [txBufPtr]                ; Increment tx buffer pointer
        mov   X, [txBufPtr]   
        mov   A, Ln_Fd          ; Load line feed into accumulator
        mov   [X + txBuf], A    
        call  putCommand              ; Send command to UPS
        call  getSerial               ; Receive result from UPS
        ret

;**********************************************************************
; This is the routine that is entered when a data item from the UPS is 
; requested and returns with the string resident in the receive buffer.
;**********************************************************************

putCommand:
        mov     A, 00h                  ; Clear the accumulator.
        mov     [txBufPtr], A           ; Reset tx buffer pointer.
        iowr    Watchdog                ; Clear watchdog timer.
        mov     X, [txBufPtr]           ; Set the index.
        mov     A,[X + txBuf]          ; Load Command Byte Zero.
        mov     [txData], A             ; Put it in the transmit register.
        call    txRoutine               ; Go transmit the byte.
        iowr    Watchdog                ; Ping the watch dog timer.
        call    delay1                  ; Give the serial device some time.
        iowr    Watchdog                ; clear watchdog timer
        ret                             ; Return to sender.


USB_EP1_ISR:
     push A
;Toggle the data 0/1 bit so it's correct for the next transaction.
     iord USB_EP1_TX_Config  
     xor A,40h
;The interrupt clears the EnableRespondToIN bit (bit 7) in the TX Config.
;Set this bit to 1 so data will go out on the next interrupt.
     or A, 91h
     iowr USB_EP1_TX_Config
;Enable interrupts and return.
     mov A, [interrupt_mask]
     ipret Global_Interrupt

;----------------------------------------------------------------------
; Reset processing
; Triggers on Reset or "reserved" interrupt.
;To be safe, initialize everything.
;----------------------------------------------------------------------

;----------------------------------------------------------------------
;The endpoint 0 ISR supports the control endpoint.
;This code enumerates and configures the hardware.
;It also responds to Set Report requests that receive data from the host.
;----------------------------------------------------------------------

USB_EP0_ISR:
     push A
     iord USB_EP0_RX_Status
;Has a Setup packet been received?
     and A, 01h
;If no, ignore.
     jz check_for_out_packet
;If yes, handle it.
;Disable endpoint 0 interrupts.
     mov A,[interrupt_mask]
     and A, 0F7h
     mov [interrupt_mask], A
     iowr Global_Interrupt
;Find out what the setup packet contains and handle the request.
      call StageOne
;Re-enable Endpoint 0 interrupts.
     mov A, [interrupt_mask]
     or A, 08h
     mov [interrupt_mask], A
     jmp done_with_packet

check_for_out_packet:
     iord USB_EP0_RX_Status
;Is it an OUT packet?
     and A, 02h
;If no, ignore it.
     jz done_with_packet
;If yes, process the received data.
;Disable Endpoint 0 interrupts.
     mov A,[interrupt_mask]
     and A, 0F7h
     mov [interrupt_mask], A
     iowr Global_Interrupt

      push X
      ;data_count holds the number of bytes left to read.
      ;X holds the index of the address to read
      ;and the index of the address to store the received data.
      ;Initialize the X register.
      mov X, 0
      
      Get_Received_Data:
      ;Find out if there are any bytes to read.
      mov A, 0
      cmp A, [data_count]
      ;Jump if nothing to read.
      jz DoneWithReceivedData
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      ;Get a byte.
      mov A, [X + Endpoint_0]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      mov [X + Data_Byte0], A
;      cpl a
;      iowr Port0_Data
      ;Decrement the number of bytes to read.
      dec [data_count]
      ;Increment the address to read.
      inc X
      ;Do another

⌨️ 快捷键说明

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