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

📄 main.asm

📁 一个以DSP为CPU读取飞利浦D12USB芯片的通讯程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	RET

;=======================================
; 子程序名称: OUTPORTC
; 功能描述: 输出命令
; 输   入: COMMAND_BUF    命令字节
; 输   出: 无
;=======================================
OUTPORTC:
	CALL 	DELAY
	OUT 	COMMAND_BUF,D12_COM   
	RET
		
;=======================================
; 函数名称: OUTPORTD
; 功能描述: 输出数据
; 输   入: DATA_BUF    数据字节
; 输   出: 无
;=======================================
OUTPORTD:
	CALL 	DELAY
	OUT		DATA_BUF,D12_DAT
	RET		
	
;=======================================
; 函数名称: INPORTD
; 功能描述: 读入数据
; 输   入: 无
; 输   出: 读到的数据(放到RAM内READ_DATA单元处)
;=======================================
INPORTD:
	CALL 	DELAY
	IN 		READ_DATA,D12_DAT
	RET

;=======================================
; 函数名称: INPORTC
; 功能描述: 读入命令
; 输   入: 无
; 输   出: 读到的命令(放到RAM内READ_COMMAND单元处)
;=======================================
INPORTC:
	CALL 	DELAY
	IN 		READ_COMMAND,D12_COM
	RET
		
;=======================================
; 函数名称: D12_ReadInterruptRegister
; 功能描述: 读取中断寄存器值
; 输   入: 无
; 输   出: 中断寄存器值放到INIT_REG中
; 注      :高8位可以不必理会。。
;=======================================
D12_ReadInterruptRegister:
	LDP 	#6
	SPLK    #0F4H,COMMAND_BUF			;读取中断寄存器命令
	CALL 	OUTPORTC

	CALL	INPORTD
	LACL 	READ_DATA
	SACL 	TEMP_BUF0
	CALL	INPORTD
	LACL 	READ_DATA
	SACL 	TEMP_BUF1
	
	BLDD	#READ_DATA,TEMP_BUF1		
	LACL    TEMP_BUF0					;将TEMP_BUF0单元内容左移0位放到累加器中
	AND     #0FFH						
	SACL    TEMP_BUF0                 	;将A中的内容左移0位,结果的低16位放到TEMP_BUF0单元中
	LACC    TEMP_BUF1,8
	AND     #0FF00H
	OR      TEMP_BUF0
	
	LACL 	TEMP_BUF0
	SACL    INIT_REG					;将得到的值放到INIT_REG单元中
	RET    
		
;=======================================
; 函数名称: D12_ReadEndpointStatus
; 功能描述: 读取端点状态
; 输   入: R0:端点索引号(0-5),要转换为(80h ~ 85h)
; 输   出: R4:端点状态
;=======================================	
D12_ReadEndpointStatus:
	LACL 	#080H
	OR 		ARR0
	SACL 	COMMAND_BUF

	CALL    OUTPORTC					;读取端点状态命令
	CALL 	INPORTD						;读取端点状态
	
	LACL 	READ_DATA					;返回值放到R4中
	SACL	ARR4	
	RET	
	
;========================================
; 函数名称: D12_ReadLastTransactionStatus
; 功能描述: 读取最后处理状态寄存器
; 输   入: R0:   端点索引号(0-5),要转换为40 ~ 45
; 输   出: R4:端点最后处理的状态
;========================================
D12_ReadLastTransactionStatus:
	LACL 	#040H
	OR 		ARR0
	SACL 	COMMAND_BUF
	CALL    OUTPORTC					;输出读取最后处理状态寄存器
	
	CALL 	INPORTD
	;LACL 	READ_DATA					;这个返回值没啥用
	;SACL 	ARR4
	RET

;========================================
; 函数名称: D12_ReadEndpoint
; 功能描述: 读取端点数据
; 输   入: R0:     端点索引号,取值 0 ~ 5 (无需转换)
;	    	R1:	    要读取的数据长度
;全局变量: R2:		接收数据指针
; 输   出: R3:		实际读得的字节数
;========================================
D12_ReadEndpoint:

	LACL 	ARR0						;发送选择端点命令
	SACL 	COMMAND_BUF
	CALL    OUTPORTC					

	CALL 	INPORTD
	BIT 	READ_DATA,BIT0
	BCND    RET_ZERO,NTC				;如果READ_DATA.0==0,则跳转到RET_ZERO处返回/返回0
   
	SPLK    #0F0H,COMMAND_BUF			;将发送读缓冲区命令放到COMMAND_BUF处
    CALL    OUTPORTC 
    
	CALL 	INPORTD						;读取保留字节
	CALL 	INPORTD						;读取数据字节的数目/长度
	
	LACL 	READ_DATA					;READ_DATA单元数据进累加器
										;if(j>len)j=len;return j;
	SUBS    ARR1						;将累加器单元内容同AAR1单元内容相减
	
	BCND	LARGE_LEN,NC
	LACL 	ARR1
	SACL 	READ_DATA
LARGE_LEN:
	MAR  	*,AR3
	LAR     AR3,ARR2

	LAR     AR4,READ_DATA				;循环次数初始化
	
READ_LOOP:	
	MAR  	*,AR3						;选择AR3间接寻址寄存器
	CALL  	INPORTD						;读数据到READ_DATA单元
	LACL	READ_DATA					;将READ_DATA单元内容读到A中
	AND 	#0FFH
    SACL    *+,0					    ;将A中内容读到AR3所指数据存储器单元
	MAR  	*,AR4						;选择AR4间接寻址寄存器
	BANZ	READ_LOOP					;判断循环次数是否到,如果没到则循环执行
	
	
	
	LACL 	#0F2H						;清缓冲区,新的信息包才可以重新被接受
	SACL 	COMMAND_BUF
	CALL    OUTPORTC
	LACL 	READ_DATA					;读数据长度返回且放到ARR3单元中
	SACL 	ARR3
RET_ZERO:
	RET  
	
;========================================
; 函数名称: D12_WriteEndpoint
; 功能描述: 把数据写入端点
; 输   入: R0:     端点索引号,取值 0 ~ 5(无需转换) 
;	     	R1:	    要写入的数据长度
; 全局变量:R2:		发送数据指针
; 输   出: R3:		实际写入的字节数
;========================================
D12_WriteEndpoint:
	LACL 	ARR0						;发送选择端点命令
	SACL 	COMMAND_BUF
	CALL    OUTPORTC					

	CALL 	INPORTD						;可选地读取一个字节

	SPLK    #0F0H,COMMAND_BUF			;发送写缓冲区命令
    CALL    OUTPORTC 
    
	SPLK    #00H,DATA_BUF				;写入一个保留字节
    CALL    OUTPORTD 

	LACL 	ARR1						;写入即将写入的字节数目
	SACL 	DATA_BUF
    CALL    OUTPORTD 

	LAR 	AR0,#ARR1					;循环次数初始化
	LAR     AR1,#ARR2					;间接寻址指针指向WRITE_DATA_POINT
WRITE_LOOP:	
	MAR  	*,AR1						;选择AR1间接寻址寄存器
	LACL	*+							;将READ_DATA单元内容读到A中,且AR1指针加1
	SACL	DATA_BUF					;将A中内容读到DATA_BUF中
	CALL  	OUTPORTD					;将数据发送出去
	MAR  	*,AR0						;选择AR0间接寻址寄存器
	BANZ	WRITE_LOOP					;判断循环次数是否到,如果没到则循环执行,且AR0减1
	
	LACL 	#0FAH						;清缓冲区,新的信息包才可以重新被接受
	SACL 	COMMAND_BUF
	CALL    OUTPORTC
	LACL 	ARR1						;读数据长度返回且放到ARR3单元中
	SACL 	ARR3
	RET  
;========================================
; 函数名称: D12_ClearBuff
; 功能描述: 清指定端点的缓冲区(包括双缓冲区)
; 输   入: R0: 端点索引号,取值 0 ~ 5 
; 输   出: 无
;========================================
D12_ClearBuff:
	LACL 	ARR0
	SACL 	COMMAND_BUF					;选择缓冲区
	CALL    OUTPORTC					

	LACL 	#0F2H
	SACL 	COMMAND_BUF
	CALL    OUTPORTC					
	
	LACL    #4
	SUBS    ARR0						;将累加器单元内容同ARR0单元内容相减
	BCND	RET_CLEAR,C 				;小于4,则直接跳出

	BLDD 	#ARR0,COMMAND_BUF	;选择第2个缓冲区
	CALL    OUTPORTC					

	BLDD 	#0F2H,COMMAND_BUF			;清空第2个缓冲区
	CALL    OUTPORTC					
RET_CLEAR:	
	RET

;========================================
;总线复位处理子程序
;========================================
bus_reset:
	RET

;========================================
;DMA结束处理
;========================================
dma_eot:
	RET
	
;========================================
;总线挂起改变
;========================================
usb_suspend:
	RET
	
;========================================
; 函数名称:  USB_ReadISR
; 功能描述:  USB 端点接收中断服务程序
; 输   入:  R0: 端点索引号(40-45)
;			 R1: 端点最大信息包大小
;			 R2: 该端点缓冲区个数(如D12的端点2有两个接收缓冲区)
; 输   出:  无
;========================================
USB_ReadISR:
	LDP  	#6
	CALL 	D12_ReadLastTransactionStatus;复位中断寄存器
	
	LACL 	ARR2
	SUB 	#1
	AND 	#03
	SACL 	ARR2
	LAR     AR0,ARR2					;循环次数初始化
										
	AND 	#0
	LACL 	#0300H						;读指针放到ARR2中为调用D12_ReadEndpoint做准备
	ADD 	#READ_DATA_POINT			;****绝对地址转换****
	SACL 	ARR2	
READ_ISR_LOOP:
	CALL 	D12_ReadEndpoint
	CALL	D12_ReadEndpointStatus		;读取的状态放在AAR1中,如果缓冲为空,立即跳出循环
	LACL	#60H
	AND    	ARR4						;这里读取的ARR1破坏了原来的AR1
	AND 	#0FFH
	BCND	RET_READ_ISR,EQ	
	MAR  	*,AR0						;选择AR0间接寻址寄存器
	BANZ	READ_ISR_LOOP				;判断循环次数是否到,如果没到则循环执行,且AR0减1
	
RET_READ_ISR:
	CALL	D12_ClearBuff				;没有任务接收数据,清空该端点接收缓冲区	
	RET
	
;=======================================
; 函数名称:  USB_WriteISR
; 功能描述:  USB 端点发送中断服务程序
; 输   入:  R0:	 端点索引号
; 输   出:  无
;=======================================
USB_WriteISR:
	CALL D12_ReadLastTransactionStatus  ;复位中断寄存器
	RET	
	
;=====================================
; 函数名称:  D12SetEpStat
; 功能描述:  
; 输   入:  R0: 端点索引号
;			 R1: 输出状态
; 输   出:  无
;=====================================
D12SetEpStat:
	LACL 	ARR0
	OR 		#040H
	SACL 	COMMAND_BUF
	CALL    OUTPORTC	
	
	LACL 	ARR1
	SACL  	DATA_BUF
	CALL    OUTPORTD	
	RET

;=====================================
; 函数名称: D12SelEp
; 功能描述: 端点选择,将内部指针初始化到选择的缓冲区起始位置
; 输   入: R0:   端点索引号,取值0 ~ 5
; 输   出: 无
;=====================================
D12SelEp:
	LACL 	ARR0
	SACL 	COMMAND_BUF
	CALL    OUTPORTC	
	RET
	
;====================================
;函数名称: D12SetAddr
;功能描述:设置D12地址
;输    入:R0     地址
;输    出:无
;====================================
D12SetAddr:
	LACL 	#0D0H
	SACL 	COMMAND_BUF
	CALL    OUTPORTC	

	LACL 	ARR0
	SACL 	DATA_BUF
	CALL    OUTPORTD	
	RET
	
;========================================
; 函数名称: D12SetEp
; 功能描述: 设置端点使能
; 输   入: R0 : 0 --- 禁止
;	     		 1 --- 允许
; 输   出: 无
;========================================
D12SetEp:
	SPLK 	#0D8H,COMMAND_BUF			;选择缓冲区
	CALL    OUTPORTC	
	
	LACL 	ARR0
	SACL 	DATA_BUF
	CALL    OUTPORTD					;输出数据
	RET
	
;========================================
; 函数名称: D12AckEp
; 功能描述: 应答Setup
; 输   入: R0: 端点索引号,取值 0 ~ 5 
; 输   出: 无
;========================================
D12AckEp:
	LDP 	#6
	LACL 	ARR0
	SACL 	COMMAND_BUF					;选择缓冲区
	CALL    OUTPORTC	

	LACL 	#0F1H
	SACL 	COMMAND_BUF
	CALL    OUTPORTC	
	
	LACL 	ARR0
	AND 	#0FFH
	BCND	RET_ACK,NEQ
	LACL 	#0F2H
	SACL 	COMMAND_BUF
	CALL    OUTPORTC	
RET_ACK:	
	RET	
	
;=========================================
; 函数名称: D12RdEp
; 功能描述: 读取端点数据
; 输   入: R0:     端点索引号,取值 0 ~ 5 
;	    	R1:     要读取的数据长度
; 全局变量:R2:		读指针
; 输   出: R3:实际读得的字节数
;========================================
D12RdEp:
	LDP 	#6
	LACL 	#0
	SACL 	COMMAND_BUF
	CALL    OUTPORTC
	
	CALL 	INPORTD
	LACL 	#1
	AND 	READ_DATA
	SACL 	READ_DATA
	
	BIT		READ_DATA,BIT0
	BCND    RDEP_RET,NTC				;要返回0
	
	LACL 	#0F0H
	SACL 	COMMAND_BUF
	CALL 	OUTPORTC
	
	CALL 	INPORTD
	CALL    INPORTD
	
   	LACL    READ_DATA
   	AND 	#00FFH
   	
	SUBS    ARR1						;将累加器单元内容同AAR1单元内容相减
	BCND	LONG1,C
	LACL 	READ_DATA
	AND 	#0FFH
	BCND 	END_READ_DATA,EQ			;如果读字节个数为0,则不读直接跳出
	SACL 	ARR1
LONG1:
	LACL 	ARR1
	SUB 	#1							;如果读字节个数不是0,那么读字节个数减1
	SACL 	ARR1						;循环次数
										;======================
	AND 	#0							;*+注意绝对地址的转化+*
	LACL 	#0300H						;======================
	ADD 	ARR2
	SACL 	ARR2	

	LAR     AR1,ARR2					;读指针
	LAR 	AR0,ARR1					;循环次数初始化
D_READ_LOOP:	
	MAR  	*,AR1						;选择AR1间接寻址寄存器
	CALL  	INPORTD						;读数据到READ_DATA单元
	LACL	READ_DATA					;将READ_DATA单元内容读到A中
    SACL    *+  					    ;将A中内容读到AR1所指数据存储器单元
	MAR  	*,AR0						;选择AR0间接寻址寄存器
	BANZ	D_READ_LOOP					;判断循环次数是否到,如果没到则循环执行
END_READ_DATA:	
	LDP 	#6
	LACL 	#0F2H
	SACL 	COMMAND_BUF					;清缓冲区,新的信息包才可以重新被接受
	CALL    OUTPORTC
	
	LACL 	ARR1
	ADD 	#1							;这里要再加一个1(因为刚才循环的时候减掉了一个1)
	SACL 	ARR3						;读数据长度返回且放到ARR3单元中
	B 		RDEP_RET1
RDEP_RET:	
	LACL 	#0
	SACL 	ARR3
RDEP_RET1:	
	RET

;========================================
; 函数名称: D12WrEp
; 功能描述: 把数据写入端点
; 输   入: R0:  端点索引号,取值 0 ~ 5 
;	     	R1:	 要写入的数据长度
; 全局变量:R2:  发送数据指针
; 输   出: 实际写入的字节数
;========================================
D12WrEp:
WAIT_LOOP:								;等待缓冲区空 
	CALL 	D12SelEp
	CALL    INPORTD	

	LACL 	READ_DATA
	AND 	#01H
	SACL 	READ_DATA  	
	BIT		READ_DATA,BIT0
	
	BCND    END_WAIT_LOOP,NTC
    B  		WAIT_LOOP
END_WAIT_LOOP:
	LACL 	#0F0H
	SACL 	COMMAND_BUF
	CALL 	OUTPORTC

	LACL 	#00H
	SACL 	DATA_BUF
	CALL 	OUTPORTD
	LACL 	ARR1
	SACL 	DATA_BUF
	CALL 	OUTPORTD

	LAR 	AR0,ARR1					;循环次数初始化
	LAR     AR1,ARR2					;间接寻址指针指向WRITE_DATA_POINT
	
	LACL 	ARR1
	AND  	#0FFH
	BCND 	END_WRITE_LOOP,EQ			;如果循环次数为0则不写数据
	
	SUB 	#1							;如果循环次数不为0,则减1

⌨️ 快捷键说明

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