📄 main.asm
字号:
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 + -