📄 ch375blk.asm
字号:
; NOP ;如果时钟频率低于16MHz则无需该指令延时
; MOV DPTR,#CH375_DAT_PORT ;数据口地址
; MOV A,#USB_VENDOR_ID_L
; MOVX @DPTR,A ;写入厂商ID的低字节
; MOV A,#USB_VENDOR_ID_H
; MOVX @DPTR,A ;写入厂商ID的高字节
; MOV A,#USB_DEVICE_ID_L
; MOVX @DPTR,A ;写入设备ID的低字节
; MOV A,#USB_DEVICE_ID_H
; MOVX @DPTR,A ;写入设备ID的高字节
; NOP
; 设置USB工作模式
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_SET_USB_MODE
MOVX @DPTR,A ;设置USB工作模式
NOP ;如果时钟频率低于16MHz则无需该指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOV A,#02H
MOVX @DPTR,A ;设置为使用内置固件的USB设备方式
NOP ;如果时钟频率低于16MHz则无需该指令延时
CH375_INIT_WT: MOVX A,@DPTR ;返回操作状态
XRL A,#CMD_RET_SUCCESS
JNZ CH375_INIT_WT ;等待操作成功,通常需要等待10uS-20uS
; 下述三条指令用于启用中断
CLR IT0 ;置外部信号为低电平触发
SETB PX0 ;置高优先级
CLR IE0 ;清中断标志
SETB EX0 ;允许CH375中断
RET
;
; 上传数据块子程序(通过批量端点上传)
; ENTRY: R0 指向存放了准备上传数据的缓冲区, R7 准备上传的数据长度, 有效数值是0到64
; USE: ACC, R0, R7, DPTR
CH375_UPLOAD: JB FLAG_SEND_WAIT,CH375_UPLOAD ;如果正在等待发送(前次发送尚未完成)则继续等待
CLR EX0 ;为了防止中途被中断而乱了顺序,必须先禁止中断
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_WR_USB_DATA7
MOVX @DPTR,A ;向USB端点2的发送缓冲区写入数据块
NOP ;如果时钟频率低于16MHz则无需该指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOV A,R7
MOVX @DPTR,A ;首先写入后续数据长度
CH375_UPLOAD_1: MOV A,@R0
INC R0
MOVX @DPTR,A ;发送数据
DJNZ R7,CH375_UPLOAD_1 ;继续发送数据直至结束
SETB FLAG_SEND_WAIT ;置等待发送标志
SETB EX0 ;允许中断
RET
;
; 上传中断数据子程序(通过中断端点上传),可选子程序
; ENTRY: R0 指向存放了准备上传数据的缓冲区, R7 准备上传的数据长度, 有效数值是0到8
; USE: ACC, R0, R7, DPTR
CH375_UP_INT: CLR EX0 ;为了防止中途被中断而乱了顺序,必须先禁止中断
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_WR_USB_DATA5
MOVX @DPTR,A ;向USB端点1的发送缓冲区写入数据块
NOP ;如果时钟频率低于16MHz则无需该指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOV A,R7
MOVX @DPTR,A ;首先写入后续数据长度
CH375_UP_INT_1: MOV A,@R0
INC R0
MOVX @DPTR,A ;发送中断数据
DJNZ R7,CH375_UP_INT_1 ;继续发送数据直至结束
SETB EX0 ;允许中断
RET
;
; 中断服务子程序
; USE: 堆栈8字节
CH375_INTER: PUSH PSW ;现场保护
PUSH ACC
PUSH DPL
PUSH DPH
; PUSH 01H ;R1
; PUSH 02H ;R2
;主程序中未使用R1/R2,所以不必入栈保护,从而提高速度
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_GET_STATUS
MOVX @DPTR,A ;获取中断状态并取消中断请求
NOP ;如果时钟频率低于16MHz则无需该指令延时,高于30MHz要多加2条指令
NOP
; 单片机向写CH375写入命令码后,应该要等2uS才能读取数据,所以时钟频率高于16MHz时需要指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOVX A,@DPTR ;返回操作状态
CLR IE0 ;清中断标志,对应于INT0中断
CJNE A,#USB_INT_EP2_OUT,CH375_INT_1 ;批量端点下传成功
LJMP CH375_DOWN_OK ; USB批量数据接收成功
CH375_INT_1: CJNE A,#USB_INT_EP2_IN,CH375_INT_2 ;批量端点上传成功
LJMP CH375_UP_OK ; USB批量数据发送成功
CH375_INT_2: CJNE A,#USB_INT_EP1_IN,CH375_INT_3 ;中断端点
LJMP CH375_UP_INT_OK ; USB中断数据发送成功
CH375_INT_3: SJMP CH375_INT_RET
CH375_INT_RET:
; POP 02H ;R2
; POP 01H ;R1
POP DPH
POP DPL
POP ACC
POP PSW ;恢复寄存器
RETI ;中断返回
;
CH375_DOWN_OK: ; USB批量数据接收成功
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_RD_USB_DATA
MOVX @DPTR,A ;从当前USB中断的端点缓冲区读取数据块,并释放缓冲区
NOP ;如果时钟频率低于16MHz则无需该指令延时,高于30MHz要多加一条指令
NOP
; 单片机向写CH375写入命令码后,应该要等2uS才能读取数据,所以时钟频率高于16MHz时需要指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOVX A,@DPTR ;首先读取后续数据长度
MOV R2,A
JZ CH375_INT_RET ;长度为0,没有数据则直接退出
MOVX A,@DPTR ;接收数据
MOV THIS_CMD_CODE,A ;保存当前命令码
CJNE A,#TEST_DOWNLOAD,IS_USB_CMD0
SJMP USB_CMD2_NEXT ;测试下传速度
USB_CMD2_RECV: MOVX A,@DPTR ;接收数据,为了测试速度,数据舍弃,24MHz的MCS51每读取一个字节需要2uS
USB_CMD2_NEXT: DJNZ R2,USB_CMD2_RECV ;继续接收数据直至结束
SJMP CH375_INT_RET
IS_USB_CMD0: MOV R1,#RECV_BUFFER ;接收缓冲区
MOV RECV_LEN,R2
SJMP CH375_INT_RECV0
CH375_INT_RECV: MOVX A,@DPTR ;接收数据
CH375_INT_RECV0: MOV @R1,A
INC R1
DJNZ R2,CH375_INT_RECV ;继续接收数据直至结束
MOV A,RECV_BUFFER ;首字节是命令码
CJNE A,#TEST_UPLOAD,IS_USB_CMD3
USB_CMD3_NEXT: ;测试上传速度
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_WR_USB_DATA7
MOVX @DPTR,A ;向USB端点2的发送缓冲区写入数据块
NOP ;如果时钟频率低于16MHz则无需该指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOV A,#40H
MOVX @DPTR,A ;首先写入后续数据长度
MOV R7,A
MOV A,TL0 ;随机数
USB_CMD3_SEND: MOVX @DPTR,A ;发送数据,为了测试速度,数据无效,24MHz的MCS51每写出一个字节需要2uS
DJNZ R7,USB_CMD3_SEND ;继续发送数据直至结束
SJMP CH375_INT_UNLK
IS_USB_CMD3: CJNE A,#TEST_START,IS_USB_CMD1
NOP ;测试过程开始
; 由于上一次测试数据上传速度时可能在上传缓冲区中遗留有数据, 所以在第二次测试前需要清除上传缓冲区
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_SET_ENDP7
MOVX @DPTR,A ;设置USB端点2的IN
NOP ;如果时钟频率低于16MHz则无需该指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOV A,#0EH ;同步触发位不变
MOVX @DPTR,A ;设置USB端点2的IN正忙,返回NAK
CLR FLAG_SEND_WAIT ;清除发送等待标志,通知应用程序可以继续发送数据
LJMP CH375_INT_RET
IS_USB_CMD1: CJNE A,#TEST_DATA,IS_USB_CMD9
NOP ;测试数据正确性
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_WR_USB_DATA7
MOVX @DPTR,A ;向USB端点2的发送缓冲区写入数据块
NOP ;如果时钟频率低于16MHz则无需该指令延时
MOV DPTR,#CH375_DAT_PORT ;数据口地址
MOV A,RECV_LEN
MOVX @DPTR,A ;首先写入后续数据长度
MOV R2,A ;刚接收到的数据长度
MOV R1,#RECV_BUFFER ;刚接收到的数据块
USB_CMD1_NEXT: MOV A,@R1
CPL A ;数据取反后返回,由计算机应用程序测试数据是否正确
MOVX @DPTR,A ;发送数据
INC R1
DJNZ R2,USB_CMD1_NEXT
LJMP CH375_INT_RET
IS_USB_CMD9: SETB FLAG_RECV_OK ;其它命令,设置接收成功标志,通知应用程序取走数据再分析
LJMP CH375_INT_RET
;
CH375_UP_OK: ; USB批量数据发送成功
MOV A,THIS_CMD_CODE
CJNE A,#TEST_UPLOAD,CH375_INT_UNLK
SJMP USB_CMD3_NEXT ;测试上传速度,继续准备上传数据
CH375_INT_UNLK: MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_UNLOCK_USB
MOVX @DPTR,A ;释放当前USB缓冲区
CLR FLAG_SEND_WAIT ;清除发送等待标志,通知应用程序可以继续发送数据
LJMP CH375_INT_RET
;
CH375_UP_INT_OK: ; USB中断数据发送成功
MOV DPTR,#CH375_CMD_PORT ;命令口地址
MOV A,#CMD_UNLOCK_USB
MOVX @DPTR,A ;释放当前USB缓冲区
LJMP CH375_INT_RET
;
;
END
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -