📄 52+d12asm.txt
字号:
;*********** Memory ************
;IntRegister MACRO 40H
#define IntRegister 40H
;ControlData MACRO 30H-3FH ;占用15个字节
;configuration MACR0 41H
;SP 61H-7FH ;堆栈 占用内部RAM的最后30个字节 占用30个字节
;标志寄存器PSW.5保存要发送数据的寻址方式 1:程序存储器间接寻址寻址 0:RAM间接寻址
;*******************************
;************R0-R7*************
;R7: 循环计数
;********************************
;********************主循环***************
ORG 0000H
AJMP START
ORG 0030H
START: ;开始
MOV SP,#61H
ACALL INIT_DATA
ACALL RECONNECT_USB
LOOP: ;主循环
MOV A,#08H
ANL A,P3
JNZ LOOP ;判断中断是否产生
LCALL RECEIVE_INT ;处理接受中断
SJMP LOOP
;****************底层函数*********************
D12_COMMAND: ;A作为参数传递
PUSH DPL
PUSH DPH
MOV DPTR,#0FF03H
MOVX @DPTR,A
POP DPH
POP DPL
RET
D12_DATA_W: ;A作为参数传递
PUSH DPL
PUSH DPH
MOV DPTR,#0FF02H
MOVX @DPTR,A
POP DPH
POP DPL
RET
D12_DATA_R: ;A作为参数传递
PUSH DPL
PUSH DPH
MOV DPTR,#0FF02H
MOVX A,@DPTR
POP DPH
POP DPL
RET
INIT_DATA:
MOV R0,#38H
MOV @R0,#00H
INC R0
MOV @R0,#01H
INC R0
MOV @R0,#00H
INC R0
MOV @R0,#00H
RET
RECONNECT_USB:
CLR P1.7
CLR P3.4
SETB P1.6
MOV A,#0f3H
ACALL D12_COMMAND
MOV A,#06H
ACALL D12_DATA_W
MOV A,#03H
ACALL D12_DATA_W
MOV A,#0D0H
ACALL D12_COMMAND
MOV A,#80H
ACALL D12_DATA_W
MOV A,#0D8H
ACALL D12_COMMAND
MOV A,#01H
ACALL D12_DATA_W
ACALL DELAY
MOV A,#0f3H
ACALL D12_COMMAND
MOV A,#016H
ACALL D12_DATA_W
MOV A,#0F4H
ACALL D12_COMMAND
ACALL D12_DATA_R
RET
;*******************************接受中断处理程序********************
;******判断中断类型处理*******
RECEIVE_INT: ;中断程序
MOV A,#0F4H ;读中断寄存器
ACALL D12_COMMAND
ACALL D12_DATA_R
MOV R0,#40H
MOV @R0,A
ANL A,#80H ;判断处理挂起事务
JZ RECEIVE_INT1 ;不是处理挂起事务跳
RET
RECEIVE_INT1:
nop ;001C
MOV A,@R0; ;判断世接收数据包吗
ANL A,#15H
JZ RECEIVE_INT2 ;不是接受数据包
ACALL RECEIVE_OUT ;处理接受数据包
RET
RECEIVE_INT2:
MOV A,@R0 ;判断世发送数据包吗
ANL A,#2AH
JZ RECEIVE_INT3 ;不是发送数据包
ACALL RECEIVE_IN ;处理发送数据包
RECEIVE_INT3:
RET ;接受中断处理完
;************处理接收和发送数据***********
;************处理接收******
RECEIVE_OUT:
MOV R0,#40H
MOV A,@R0
ANL A,#01H
JZ RECEIVE_OUT1
MOV A,#40H
ACALL D12_COMMAND
MOV DPTR,#0FF02H
MOVX A,@DPTR
ANL A,#20H
JZ RECEIVE_OUT3
ACALL SETUP_READ
ACALL HandleSetup
SJMP RECEIVE_OUT3
RECEIVE_OUT1:
MOV A,@R0
ANL A,#04H
JZ RECEIVE_OUT2
MOV A,#42H
ACALL D12_COMMAND
SJMP RECEIVE_OUT3
RECEIVE_OUT2:
MOV A,@R0
ANL A,#10H
JZ RECEIVE_OUT3
MOV A,#44H
ACALL D12_COMMAND
RECEIVE_OUT3:
RET
RECEIVE_IN:
MOV R0,#40H
MOV A,@R0
ANL A,#02H
JZ RECEIVE_IN1
MOV R0,#39H ;读端点标示
MOV @R0,#01H
SJMP RECEIVE_IN3
RECEIVE_IN1:
MOV A,@R0
ANL A,#08H
JZ RECEIVE_IN2
MOV R0,#39H ;读端点标示
MOV @R0,#03H
SJMP RECEIVE_IN3
RECEIVE_IN2:
MOV A,@R0
ANL A,#20H
JZ RECEIVE_IN3
MOV R0,#39H ;读端点标示
MOV @R0,#05H
RECEIVE_IN3:
MOV A,@R0
ADD A,#40H
ACALL D12_COMMAND ;// 读 IN 最后状态
ACALL D12_DATA_R
ANL A,#01H
JZ RECEIVE_IN4
ACALL USB_SUBMIT
RECEIVE_IN4:
RET
USB_SUBMIT:
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
CLR C
MOV A,@R1
SUBB A,@R0
JNC SUB_SUBMIT1
MOV A,@R1
MOV @R0,A
SUB_SUBMIT1:
;****循环初始化****
MOV A,@R0
MOV R7,A ;设置循环计数器
;*******************
MOV R0,#39H ;读端点标示
MOV A,@R0
MOV DPTR,#0FF03H ;选择端点
MOVX @DPTR,A
MOV A,#0F0H
MOVX @DPTR,A ;写入数据命令
;*****得到数据指针 pData*****
MOV R0,#3CH
MOV A,@R0
MOV R2,A ;用R2来保存当前数据指针偏移量
MOV R0,#3DH
MOV A,@R0
MOV R3,A ;用R3来保存当前数据指针基址高字节
MOV R0,#3EH
MOV A,@R0
MOV R4,A ;用R4来保存当前数据指针基址低字节
;******************
;****开始向端点写入数据***
MOV DPTR,#0FF02H ;向端点写入数据命令
MOV A,#00H
MOVX @DPTR,A
MOV A,R7
MOVX @DPTR,A ;写入数据的实际长度
SUB_SUBMIT_LOOP:
;***循环开始***
JB PSW.5,SUB_SUBMIT_LOOP1
MOV A,R2
MOV R0,A
MOV A,@R0
ACALL D12_DATA_W
SJMP SUB_SUBMIT_LOOP2
SUB_SUBMIT_LOOP1:
MOV DPH,R3
MOV DPL,R4
MOV A,R2
MOVC A,@A+DPTR
nop
nop
nop
nop
nop
ACALL D12_DATA_W
SUB_SUBMIT_LOOP2:
INC R2
DJNZ R7,SUB_SUBMIT_LOOP
;****循环结束***
MOV R0,#3CH ;保存当前数据指针偏移量
MOV A,R2
MOV @R0,A
;计算剩余数据个数
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
CLR C
MOV A,@R1
SUBB A,@R0
MOV @R1,A
; 应答SETUP包,使能(清 OUT 缓冲区、使能 IN 缓冲区)命
MOV R0,#39H ;读端点标示
CJNE @R0,#01H,SUB_SUBMIT2
MOV A,#0F1H
ACALL D12_COMMAND
SUB_SUBMIT2:
MOV A,#0FAH
ACALL D12_COMMAND
RET
SETUP_READ:
MOV A,#0H
ACALL D12_COMMAND
MOV A,#0F0H
ACALL D12_COMMAND
ACALL D12_DATA_R
ACALL D12_DATA_R
MOV R7,#08H ;读次数计数器
MOV R0,#30H ;ControlData
MOV DPTR,#0FF02H ;读地址
SETUP_READ_LOOP:
MOVX A,@DPTR
MOV @R0,A
INC R0
DJNZ R7,SETUP_READ_LOOP
MOV A,#0F1H
ACALL D12_COMMAND
MOV A,#0F2H
ACALL D12_COMMAND
RET
HandleSetup:
MOV R0,#30H
MOV A,@R0
ANL A,#020H ;判断处理挂起事务
JZ HandleSetup1
;ADD ClassFunctionTable
RET
HandleSetup1:
MOV R0,#31H
MOV A,@R0
ANL A,#0FH
SETB C
SUBB A,#0BH
JNC HandleSetup2 ;类型大于#b跳转
MOV A,@R0 ;跳转道相应的功能请求
ANL A,#0FH
RL A
MOV DPTR,#StandardDeviceRequest
JMP @A+DPTR
HandleSetup2:
RET
;************************************************
;****************请求功能*******************
RESERVED: ;reserved
MOV A,#040H
ACALL D12_COMMAND
MOV A,#01H
ACALL D12_DATA_W
MOV A,#041H
ACALL D12_COMMAND
MOV A,#01H
ACALL D12_DATA_W
MOV A,#0F1H
ACALL D12_COMMAND
clr p1.0
RET
;*****get_status*****
GET_STATUS:
MOV R0,#30H
MOV A,@R0
CJNE A,#80H,GET_STATUS1:
MOV @R0,#00H
INC R0
MOV @R0,#00H
SJMP GET_STATUS3:
GET_STATUS1:
CJNE A,#81H,GET_STATUS2:
MOV @R0,#00H
INC R0
MOV @R0,#00H
SJMP GET_STATUS3:
GET_STATUS2:
CJNE A,#82H,GET_STATUS3:
MOV @R0,#00H
INC R0
MOV @R0,#00H
SJMP GET_STATUS3:
GET_STATUS3:
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
MOV @R0,#02H
MOV @R1,#02H
;设置数据指针
MOV R0,#3CH
MOV @R0,#30H ;用R3来保存当前数据指针偏移量
INC R0
MOV @R0,#00H ;用R4来保存当前数据指针基址高字节
INC R0
MOV @R0,#00H ;用R5来保存当前数据指针基址低字节
CLR PSW.5
ACALL USB_SUBMIT
RET
;****set_address*****
SET_ADDRESS:
MOV A,#0D0H
ACALL D12_COMMAND
MOV R0,#32H
MOV A,#80H
ORL A,@R0
ACALL D12_DATA_W
MOV R0,#3AH
MOV @R0,#00H
ACALL USB_SUBMIT
RET
GET_DESCRIPTOR:
MOV R0,#3AH ;wLength
MOV @R0,#10H
MOV R0,#33H
MOV A,@R0
CJNE A,#01H,GET_DESCRIPTOR1
MOV R0,#3BH ;wCount
MOV @R0,#12H
MOV R0,#3CH ;设置数据指针
MOV @R0,#00H
INC R0
MOV @R0,#HIGH DeviceDescr
INC R0
MOV @R0,#LOW DeviceDescr
AJMP GET_DESCRIPTOR_EXIT
GET_DESCRIPTOR1:
CJNE A,#02H,GET_DESCRIPTOR2
MOV R0,#3BH ;wCount
MOV @R0,#09H
MOV R0,#3CH ;设置数据指针
MOV @R0,#00H
INC R0
MOV @R0,#HIGH ConfigDescr
INC R0
MOV @R0,#LOW ConfigDescr
AJMP GET_DESCRIPTOR_EXIT
GET_DESCRIPTOR2:
CJNE A,#03H,GET_DESCRIPTOR23:
MOV R0,#32H
MOV A,@R0
CJNE A,#00H,GET_DESCRIPTOR21
MOV R0,#3BH ;wCount
MOV @R0,#03H
MOV R0,#3CH ;设置数据指针
MOV @R0,#00H
INC R0
MOV @R0,#HIGH USBStringLanguageDescription
INC R0
MOV @R0,#LOW USBStringLanguageDescription
AJMP GET_DESCRIPTOR_EXIT
GET_DESCRIPTOR21:
CJNE A,#01H,GET_DESCRIPTOR22
MOV R0,#3BH ;wCount
MOV @R0,#0FH
MOV R0,#3CH ;设置数据指针
MOV @R0,#00H
INC R0
MOV @R0,#HIGH USBStringDescription1
INC R0
MOV @R0,#LOW USBStringDescription1
AJMP GET_DESCRIPTOR_EXIT
GET_DESCRIPTOR22:
CJNE A,#02H,GET_DESCRIPTOR23
MOV R0,#3BH ;wCount
MOV @R0,#0FH
MOV R0,#3CH ;设置数据指针
MOV @R0,#00H
INC R0
MOV @R0,#HIGH USBStringDescription2
INC R0
MOV @R0,#LOW USBStringDescription2
AJMP GET_DESCRIPTOR_EXIT
GET_DESCRIPTOR23:
ACALL RESERVED
RET
GET_DESCRIPTOR_EXIT:
SETB PSW.5
ACALL USB_SUBMIT
RET
;*********get_configuration********
GET_CONFIGURATION:
MOV R0,#41H
MOV A,@R0
JZ GET_CONFIGURATION1
MOV A,#01H
SJMP GET_CONFIGURATION2
GET_CONFIGURATION1:
MOV A,#00H
GET_CONFIGURATION2:
MOV R0,#30H
MOV @R0,A
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
MOV @R0,#01H
MOV @R1,#01H
;设置数据指针
MOV R0,#3CH
MOV @R0,#30H ;用R3来保存当前数据指针偏移量
INC R0
MOV @R0,#00H ;用R4来保存当前数据指针基址高字节
INC R0
MOV @R0,#00H ;用R5来保存当前数据指针基址低字节
CLR PSW.5
ACALL USB_SUBMIT
RET
;*********set_configuration********
SET_CONFIGURATION:
MOV R0,#30H
MOV A,@R0
JNZ SET_CONFIGURATION2
MOV R0,#41H ;configuration
MOV @R0,00H
MOV R0,#3AH
MOV @R0,#00H
ACALL USB_SUBMIT
MOV A,#0D8H
ACALL D12_COMMAND
MOV R0,#32H
MOV A,@R0
JNZ SET_CONFIGURATION1
MOV A,#00H
ACALL D12_DATA_W
SJMP SET_CONFIGURATION_EXIT
SET_CONFIGURATION1:
CJNE A,#01H,SET_CONFIGURATION_EXIT
MOV A,#01H
ACALL D12_DATA_W
MOV A,#0D8H
ACALL D12_COMMAND
MOV A,#00H
ACALL D12_DATA_W
SJMP SET_CONFIGURATION_EXIT
SET_CONFIGURATION2:
CJNE A,#01H,SET_CONFIGURATION3
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
MOV @R0,#00H
MOV @R1,#00H
;设置数据指针
MOV R0,#3CH
MOV @R0,#30H ;用R3来保存当前数据指针偏移量
INC R0
MOV @R0,#00H ;用R4来保存当前数据指针基址高字节
INC R0
MOV @R0,#00H ;用R5来保存当前数据指针基址低字节
CLR PSW.5
ACALL USB_SUBMIT
MOV A,#0D8H
ACALL D12_COMMAND
MOV A,#00H
ACALL D12_DATA_W
MOV A,#0D8H
ACALL D12_COMMAND
MOV A,#01H
ACALL D12_DATA_W
MOV R0,#41H ;configuration
MOV @R0,0FFH
SJMP SET_CONFIGURATION_EXIT
SET_CONFIGURATION3:
ACALL RESERVED
SET_CONFIGURATION_EXIT:
RET
GET_INTERFACE:
MOV R0,#30H
MOV @R0,#00H
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
MOV @R0,#01H
MOV @R1,#01H
;设置数据指针
MOV R0,#3CH
MOV @R0,#30H ;用R3来保存当前数据指针偏移量
INC R0
MOV @R0,#00H ;用R4来保存当前数据指针基址高字节
INC R0
MOV @R0,#00H ;用R5来保存当前数据指针基址低字节
CLR PSW.5
ACALL USB_SUBMIT
RET
SET_INTERFACE:
MOV R0,#32H
MOV A,@R0
JNZ SET_INTERFACE1
MOV R0,#33H
MOV A,@R0
JNZ SET_INTERFACE1
MOV R0,#3AH ;wLength
MOV R1,#3BH ;wCount
MOV @R0,#00H
MOV @R1,#00H
;设置数据指针
MOV R0,#3CH
MOV @R0,#30H ;用R3来保存当前数据指针偏移量
INC R0
MOV @R0,#00H ;用R4来保存当前数据指针基址高字节
INC R0
MOV @R0,#00H ;用R5来保存当前数据指针基址低字节
CLR PSW.5
ACALL USB_SUBMIT
SJMP SET_INTERFACE_EXIT
SET_INTERFACE1:
MOV A,#40H
ACALL D12_COMMAND
MOV A,#01H
MOV A,#41H
ACALL D12_COMMAND
MOV A,#01H
SET_INTERFACE_EXIT:
RET
StandardDeviceRequest:
AJMP GET_STATUS
AJMP RESERVED;//clear_feature,
AJMP RESERVED;
AJMP RESERVED;//set_feature,
AJMP RESERVED;
AJMP SET_ADDRESS
AJMP GET_DESCRIPTOR
AJMP RESERVED;reserved,
AJMP GET_CONFIGURATION
AJMP SET_CONFIGURATION
AJMP GET_INTERFACE
AJMP SET_INTERFACE
AJMP RESERVED;
AJMP RESERVED;
AJMP RESERVED;
AJMP RESERVED;
DELAY: ;延时子程序,就是上节课中的延时子程序
PUSH R1
PUSH R2
PUSH R3
MOV R1,#50
DELAY0:
MOV R2,#50
DELAY1:
MOV R3,#100
DJNZ R3,$
DJNZ R2,DELAY1
DJNZ R1,DELAY0
POP R3
POP R2
POP R1
RET ;延时子程序结束,返回到调用处的下一句
DeviceDescr:
DB 12H
DB 01H
DW 0101H;1001
DB 00H
DB 00H
DB 00H
DB 10H
DW 1807h;0471H
DW 0200h;1111H
DW 0001H
DB 01H;1
DB 02H;2
DB 00H
DB 01H
ConfigDescr:
DB 09H
DB 02H
DW 2000H
DB 01H
DB 01H
DB 00H
DB 0a0H
DB 64H
USBStringLanguageDescription:
;//sizeof(USBStringLanguageDescription),
;DB 03H
DB 03H
DB 09H
DB 04H
USBStringDescription1:
;sizeof(USBStringDescription1),
;DB 0FH
DB 03H
DB 'C'
DB 0H
DB 'y'
DB 0H
DB 'p'
DB 0H
DB 'r'
DB 0H
DB 'e'
DB 0H
DB 's'
DB 0H
DB 's'
DB 0H
DB ' '
USBStringDescription2:
;sizeof(USBStringDescription1),
;DB 0FH
DB 03H
DB 'C'
DB 0H
DB 'y'
DB 0H
DB 'p'
DB 0H
DB 'r'
DB 0H
DB 'e'
DB 0H
DB 's'
DB 0H
DB 's'
DB 0H
DB ' '
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -