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

📄 ch375451.asm

📁 CH372 USB-UART Chip Specification Document,for reference only
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;				MOV   BUF_ADDR_L,DPL
;				MOV   BUF_ADDR_H,DPH
;				MOV   DPTR,#CH375_DAT_PORT	;数据口地址
;				MOVX  @DPTR,A				;将数据写入批量端点的发送缓冲区
;				DJNZ  R7,CH375_INT_UP0		;继续写入数据直至结束
;				LJMP  CH375_INT_RET

CH375_INT_CMD3:	CJNE  A,#DEMO_TEST_DATA,CH375_INT_CMD4
; 测试数据传输命令,将PC机发来的当前命令包的所有数据按位取反后返回
				MOV   DPTR,#CH375_CMD_PORT	;命令口地址
				MOV   A,#CMD_WR_USB_DATA7
				MOVX  @DPTR,A				;向批量端点的发送缓冲区写入数据块
				NOP							;如果时钟频率低于16MHz则无需该指令延时
				MOV   DPTR,#CH375_DAT_PORT	;数据口地址
				MOV   A,#CONST_CMD_LEN
				MOV   R7,A
				MOVX  @DPTR,A				;首先写入后续数据长度,也就是命令包的长度
				MOV   R0,#CMD_BUFFER		;命令包缓冲区
CH375_TEST_DAT:	MOV   A,@R0
				CPL   A                     ;数据按位取反
				MOVX  @DPTR,A
				INC   R0
				DJNZ  R7,CH375_TEST_DAT     ;将命令包数据按位取反写入批量端点的发送缓冲区
				MOV   BUF_LEN_L,#00H		;剩余数据长度为0,只发送一组数据
				MOV   BUF_LEN_H,#00H
				LJMP  CH375_INT_RET

CH375_INT_CMD4:	CJNE  A,#DEMO_CH451_CMD,CH375_INT_CMD5
; PC发送命令给CH451
				MOV   A,CMD_BUFFER_ADRH
				MOV   CH451_CMD_H,A         ;高4位命令
				MOV   A,CMD_BUFFER_ADRL     ;低8位命令
				MOV   CH451_CMD_L,A
; 为了防止在CH375中断服务程序打断主程序中的CH451_READ而执行CH451_WRITE产生错误
; 所以在此保存CH451的命令码由主程序在空闲时发给CH451
				LJMP  CH375_INT_RET

CH375_INT_CMD5:	NOP							;未定义的命令码,不支持,放弃
				LJMP  CH375_INT_RET

; 接收下传的数据块,每组数据的长度不超过64字节
CH375_INT_DN1:
; 下面是向MCS51单片机的内部RAM保存下传的数据,速度是外部RAM快3倍
				MOV   R0,BUF_ADDR_L			;由于演示板中没有外部RAM,并且外部RAM的效率很低,所以用内部RAM示范
				MOV   R0,#40H				;为了防止做测试时误操作到数据区域00H-3FH,临时指定专用缓冲区
CH375_INT_DN0:	MOVX  A,@DPTR				;从批量端点的接收缓冲区读取数据
				MOV   @R0,A					;向内部RAM缓冲区保存接收到的下传数据
				INC   R0					;在12MHz时钟是这种方法每复制1字节大概需要6uS
				DJNZ  R7,CH375_INT_DN0		;继续取出数据直至结束
				LJMP  CH375_INT_RET
; 下面从MCS51单片机的外部RAM读取数据并上传,如果采用较高时钟并且具有双DPTR的单片机则速度可以快些
;CH375_INT_DN0:	MOV   DPTR,#CH375_DAT_PORT	;数据口地址
;				MOVX  A,@DPTR				;从批量端点的接收缓冲区读取数据
;				MOV   DPL,BUF_ADDR_L		;由于MCS51单片机读取外部RAM的效率很低
;				MOV   DPH,BUF_ADDR_H		;所以在12MHz时钟是这种方法每复制1字节大概需要18uS
;				MOVX  @DPTR,A				;向外部RAM缓冲区保存接收到的下传数据
;				INC   DPTR					;缓冲区地址增量
;				MOV   BUF_ADDR_L,DPL
;				MOV   BUF_ADDR_H,DPH
;				DJNZ  R7,CH375_INT_DN0		;继续取出数据直至结束
;				LJMP  CH375_INT_RET

; USB批量数据发送成功
CH375_UP_OK:
; 假定在命令包中指定了总共需要上传的数据长度,则根据该长度上传数据
				MOV   A,BUF_LEN_L			;检查剩余长度
				ORL   A,BUF_LEN_H
				JZ    CH375_INT_UNLK		;剩余数据长度为0,没有数据需要发送,解锁后直接退出
				CLR   C
				MOV   A,BUF_LEN_L
				SUBB  A,#40H				;检查剩余长度
				MOV   R5,A
				MOV   A,BUF_LEN_H
				SUBB  A,#00H
				MOV   R6,A
				JC    CH375_UP_END			;剩余长度不足一个数据包的最大长度64
				MOV   R7,#40H
				MOV   BUF_LEN_L,R5
				MOV   BUF_LEN_H,R6
				SJMP  CH375_UP_NEXT
CH375_UP_END:	MOV   R7,BUF_LEN_L
				MOV   BUF_LEN_L,#00H
				MOV   BUF_LEN_H,#00H
CH375_UP_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,R7					;每次最多上传64个字节的数据
				MOVX  @DPTR,A				;首先写入后续数据长度
; 下面是从MCS51单片机的内部RAM读取数据并上传,速度是外部RAM快3倍
				MOV   R0,BUF_ADDR_L			;由于演示板中没有外部RAM,并且外部RAM的效率很低,所以用内部RAM示范
CH375_INT_UP1:	MOV   A,@R0					;从内部RAM缓冲区取出准备上传的数据
				INC   R0					;在12MHz时钟是这种方法每复制1字节大概需要6uS
				MOVX  @DPTR,A				;将数据写入批量端点的发送缓冲区
				DJNZ  R7,CH375_INT_UP1		;继续写入数据直至结束
				LJMP  CH375_INT_UNLK
; 下面从MCS51单片机的外部RAM读取数据并上传,如果采用较高时钟并且具有双DPTR的单片机则速度可以快些
;CH375_INT_UP1:	MOV   DPL,BUF_ADDR_L		;由于MCS51单片机读取外部RAM的效率很低
;				MOV   DPH,BUF_ADDR_H		;所以在12MHz时钟是这种方法每复制1字节大概需要18uS
;				MOVX  A,@DPTR				;从外部RAM缓冲区取出准备上传的数据
;				INC   DPTR					;缓冲区地址增量
;				MOV   BUF_ADDR_L,DPL
;				MOV   BUF_ADDR_H,DPH
;				MOV   DPTR,#CH375_DAT_PORT	;数据口地址
;				MOVX  @DPTR,A				;将数据写入批量端点的发送缓冲区
;				DJNZ  R7,CH375_INT_UP1		;继续写入数据直至结束
;				LJMP  CH375_INT_UNLK

; 收到上传成功中断后,在退出之前必须解锁USB缓冲区,以便继续收发数据
CH375_INT_UNLK:	MOV   DPTR,#CH375_CMD_PORT	;命令口地址
				MOV   A,#CMD_UNLOCK_USB
				MOVX  @DPTR,A				;释放当前USB缓冲区
				LJMP  CH375_INT_RET

; USB中断数据发送成功
CH375_UP_INT_OK:	MOV   DPTR,#CH375_CMD_PORT	;命令口地址
				MOV   A,#CMD_UNLOCK_USB
				MOVX  @DPTR,A				;释放当前USB缓冲区
				CLR   FLAG_INT_WAIT			;清中断等待标志,通知应用程序可以继续发送中断数据
				LJMP  CH375_INT_RET
;
;****************************************************************************
;
; 初始化子程序
CH451_INIT:		CLR   CH451_DIN        ;先低后高,输出上升沿通知CH451选择4线串行接口
				SETB  CH451_DCLK       ;置为默认的高电平
				SETB  CH451_DIN
				SETB  CH451_LOAD
				SETB  CH451_DOUT       ;置为输入
; 下述三条指令用于键盘中断
				CLR   IT1              ;置外部信号为低电平触发
				CLR   IE1              ;清中断标志
				CLR   PX1              ;置低优先级
				SETB  EX1              ;允许键盘中断
				RET
;
;
; 输出命令子程序
; ENTRY: B-ACC 待写的12位数据, 低8位在ACC中, 高4位在B的低4位中
; USE:   ACC, B, R7
CH451_WRITE:	CLR   EX1              ;禁止键盘中断
				CLR   CH451_LOAD       ;命令开始,此命令可以放在后面
				MOV   R7,#08H          ;将ACC中8位送出
CH451_WRITE_8:	RRC   A                ;低位在前,高位在后
				CLR   CH451_DCLK
				MOV   CH451_DIN,C      ;送出一位数据
				SETB  CH451_DCLK       ;产生时钟上升沿通知CH451输入位数据
				DJNZ  R7,CH451_WRITE_8 ;位数据未完继续
				MOV   A,B
				MOV   R7,#04H          ;将B中4位送出
CH451_WRITE_4:	RRC   A                ;低位在前,高位在后
				CLR   CH451_DCLK
				MOV   CH451_DIN,C      ;送出一位数据
				SETB  CH451_DCLK       ;产生时钟上升沿通知CH451输入位数据
				DJNZ  R7,CH451_WRITE_4 ;位数据未完继续
				SETB  CH451_LOAD       ;产生加载上升沿通知CH451处理命令数据
				SETB  EX1              ;允许键盘中断
				RET
;
;
; 输入键值子程序
; EXIT:  ACC 键值数据
; USE:   ACC, R7
CH451_READ:		CLR   EX1              ;禁止键盘中断
				CLR   CH451_LOAD       ;命令开始
				MOV   A,#07H           ;读取键值命令的高4位0111B
				MOV   R7,#04H          ;忽略12位命令的低8位
CH451_READ_4:	RRC   A                ;低位在前,高位在后
				CLR   CH451_DCLK
				MOV   CH451_DIN,C      ;送出一位数据
				SETB  CH451_DCLK       ;产生时钟上升沿锁通知CH451输入位数据
				DJNZ  R7,CH451_READ_4  ;位数据未完继续
				SETB  CH451_LOAD       ;产生加载上升沿通知CH451处理命令数据
				CLR   A                ;先清除键值单元以便移位
				MOV   R7,#07H          ;读入7位键值
CH451_READ_7:	MOV   C,CH451_DOUT     ;读入一位数据
				CLR   CH451_DCLK       ;产生时钟下升沿通知CH451输出下一位
				RLC   A                ;数据移入ACC,高位在前,低位在后
				SETB  CH451_DCLK
				DJNZ  R7,CH451_READ_7  ;位数据未完继续
				CLR   IE1              ;清中断标志,读操作过程中有低电平脉冲
				SETB  EX1              ;允许键盘中断
				RET
;
;
; 键盘中断子程序
; USE:   堆栈6字节
CH451_INTER:	PUSH  PSW              ;现场保护
				PUSH  ACC
				CLR   CH451_LOAD       ;命令开始
				MOV   A,#0F7H          ;读键值命令,忽略12位命令的低8位,高4位用作结束标志
CH451_INTER_4:	SETB  C                ;在高位添0以检测位数据结束
				RRC   A                ;低位在前,高位在后
				CLR   CH451_DCLK
				MOV   CH451_DIN,C      ;送出一位数据
				SETB  CH451_DCLK       ;产生时钟上升沿锁通知CH451输入位数据
				CJNE  A,#0FFH,CH451_INTER_4 ;位数据未完继续,共4位,完成后为0FFH
				SETB  CH451_LOAD       ;产生加载上升沿通知CH451处理命令数据
				MOV   A,#0FCH          ;该数据用以检测位数据结束
CH451_INTER_7:	MOV   C,CH451_DOUT     ;读入一位数据
				CLR   CH451_DCLK       ;产生时钟下升沿通知CH451输出下一位
				RLC   A                ;数据移入ACC,高位在前,低位在后
				SETB  CH451_DCLK
				JC    CH451_INTER_7    ;位数据未完继续,共7位,完成后才移出0
				MOV   CH451_KEY,A      ;保存键值
				POP   ACC
				POP   PSW
				CLR   IE1              ;清中断标志,该指令需根据实际情况作修改
				RETI                   ;中断返回
;
;*********************************************************************************************************************
;
; 以毫秒为单位延时
; ENTRY: R7 延时毫秒数
; USE:   ACC, R7
DELAY_MS:		MOV   A,#0FAH				;250*(1*6+2)*0.5=1000uS
DELAY_1MS:		NOP
				NOP
				NOP
				NOP
				NOP
				NOP
				DJNZ  ACC,DELAY_1MS			;每周期延时1毫秒
				DJNZ  R7,DELAY_MS
				RET
;
;*********************************************************************************************************************
;
END
;

⌨️ 快捷键说明

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