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

📄 avr309-usb 到 uart 协议转换程序.txt

📁 AVR309-USB 到 UART 协议转换程序。
💻 TXT
📖 第 1 页 / 共 5 页
字号:
;***************************************************************************
;* U S B   S T A C K   F O R   T H E   A V R   F A M I L Y
;*
;* 文件名               :"USB90S2313.asm"
;* 标题                 :AVR309:USB 到 UART 协议转换程序 (简易的 - 少量的FIFO)
;* 日期                 :24.11.2004
;* 版本                 :2.2
;* 目标 MCU             :AT90S2313-10
;* 创造者               :Ing. Igor Cesko
;*                      Slovakia
;*                      cesko@internet.sk
;*                      http://www.cesko.host.sk
;* 翻译                 :吴险峰
;* 描述:
;* 通过 MCU 执行 USB 协议,完成软 USB 接口:
;* 设备:
;*   通用的 USB 接口 (8-bit I/O口 + RS232 串行通讯 + EEPROM)
;*  + 附加的 RS232 FIFO 缓冲器
;*
;* 使用 12 MHz 振荡器 ( MCU 超频 !!!)
;*
;*
;* 添加自己的功能 - 请看: TEMPLATE OF YOUR FUNCTION
;*
;* 做成自己公司的产品必须更改 VendorUSB ID (VID)
;* 获得分配到自己公司的 VID (更多的信息请查看 www.usb.org)
;*
;***************************************************************************
.include "2313def.inc"
;- - - - - - - - - - I/O定义 - - - - - - - - - -
.equ   inputport            =PINB
.equ   outputport           =PORTB
.equ   USBdirection         =DDRB
.equ   DATAplus             =1                  ;PB1模拟 D+ 信号
.equ   DATAminus            =0                  ;PB0模拟 D- 信号 - 接1.5K上拉电阻,低速模式
.equ   USBpinmask           =0b11111100         ;屏蔽 PB 低2位 (D+,D-)
.equ   USBpinmaskDplus      =~(1<<DATAplus)     ;屏蔽 PB D+ 位
.equ   USBpinmaskDminus     =~(1<<DATAminus)    ;屏蔽 PB D- 位

.equ   TSOPPort             =PINB
.equ   TSOPpullupPort       =PORTB
.equ   TSOPPin              =2                  ;红外遥控接收头 TSOP1738 输出到 PB2

.equ   LEDPortLSB           =PORTD              ;用户自定义 PD 输出口
.equ   LEDPinLSB            =PIND               ;用户自定义 PD 输入口
.equ   LEDdirectionLSB      =DDRD               ;用户自定义 PD 口方向
.equ   LEDPortMSB           =PORTB              ;用户自定义 PB 输出口
.equ   LEDPinMSB            =PINB               ;用户自定义 PB 输入口
.equ   LEDdirectionMSB      =DDRB               ;用户自定义 PB 口方向
.equ   LEDlsb0              =3                  ;用户自定义口 PD3
.equ   LEDlsb1              =5                  ;用户自定义口 PD5
.equ   LEDlsb2              =6                  ;用户自定义口 PD6
.equ   LEDmsb3              =3                  ;用户自定义口 PB3
.equ   LEDmsb4              =4                  ;用户自定义口 PB4
.equ   LEDmsb5              =5                  ;用户自定义口 PB5
.equ   LEDmsb6              =6                  ;用户自定义口 PB6
.equ   LEDmsb7              =7                  ;用户自定义口 PB7
;
;- - - - - - - - - - 常数定义 - - - - - - - - -
.equ   SOPbyte              =0b10000000         ;起始包(Start) byte
.equ   DATA0PID             =0b11000011         ;数据循环位0(DATA0) 令牌(PID)
.equ   DATA1PID             =0b01001011         ;数据循环位1(DATA1) 令牌(PID)
.equ   OUTPID               =0b11100001         ;输出(OUT) 令牌(PID)
.equ   INPID                =0b01101001         ;输入(IN) 令牌(PID)
.equ   SOFPID               =0b10100101         ;SOF 令牌(PID)
.equ   SETUPPID             =0b00101101         ;设置(SETUP) 令牌(PID)
.equ   ACKPID               =0b11010010         ;ACK 令牌(PID)
.equ   NAKPID               =0b01011010         ;NAK 令牌(PID)
.equ   STALLPID             =0b00011110         ;STALL 令牌(PID)
.equ   PREPID               =0b00111100         ;PRE 令牌(PID)

.equ   nSOPbyte             =0b00000001         ;起始包(Start) byte - 反向移位
.equ   nDATA0PID            =0b11000011         ;数据循环位0(DATA0) 令牌(PID) - 反向移位
.equ   nDATA1PID            =0b11010010         ;数据循环位1(DATA1) 令牌(PID) - 反向移位
.equ   nOUTPID              =0b10000111         ;输出(OUT) 令牌(PID) - 反向移位
.equ   nINPID               =0b10010110         ;输入(IN) 令牌(PID) - 反向移位
.equ   nSOFPID              =0b10100101         ;SOF 令牌(PID) - 反向移位
.equ   nSETUPPID            =0b10110100         ;设置(SETUP) 令牌(PID) - 反向移位
.equ   nACKPID              =0b01001011         ;ACK 令牌(PID) - 反向移位
.equ   nNAKPID              =0b01011010         ;NAK 令牌(PID) - 反向移位
.equ   nSTALLPID            =0b01111000         ;STALL 令牌(PID) - 反向移位
.equ   nPREPID              =0b00111100         ;PRE 令牌(PID) - 反向移位

.equ   nNRZITokenPID        =~0b10000000        ;令牌屏蔽 (IN,OUT,SOF,SETUP) - 反向移位 反向不归零码(NRZI)
.equ   nNRZISOPbyte         =~0b10101011        ;起始包(Start) byte - 反向移位 反向不归零码(NRZI)
.equ   nNRZIDATA0PID        =~0b11010111        ;数据循环位0(DATA0) 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZIDATA1PID        =~0b11001001        ;数据循环位1(DATA1) 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZIOUTPID          =~0b10101111        ;输出(OUT) 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZIINPID           =~0b10110001        ;输入(IN) 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZISOFPID          =~0b10010011        ;SOF 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZISETUPPID        =~0b10001101        ;设置(SETUP) 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZIACKPID          =~0b00100111        ;ACK 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZINAKPID          =~0b00111001        ;NAK 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZISTALLPID        =~0b00000111        ;STALL 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZIPREPID          =~0b01111101        ;PRE 令牌(PID) - 反向移位 反向不归零码(NRZI)
.equ   nNRZIADDR0           =~0b01010101        ;地址=0 - 反向移位 反向不归零码(NRZI)

                   ;工作状态
.equ   BaseState            =0                  ;
.equ   SetupState           =1                  ;Setup状态
.equ   InState              =2                  ;
.equ   OutState             =3                  ;
.equ   SOFState             =4                  ;
.equ   DataState            =5                  ;
.equ   AddressChangeState   =6                  ;

                   ;工作标志
.equ   DoNone               =0
.equ   DoReceiveOutData     =1
.equ   DoReceiveSetupData   =2                  ;要求或正在处理设置包(Setup)
.equ   DoPrepareOutContinuousBuffer     =3      ;从缓冲区输出连续数据
.equ   DoReadySendAnswer    =4


.equ   CRC5poly             =0b00101            ;CRC5 polynom
.equ   CRC5zvysok           =0b01100            ;CRC5 zvysok po uspesnpm CRC5
.equ   CRC16poly            =0b1000000000000101 ;CRC16 polynom
.equ   CRC16zvysok          =0b1000000000001101 ;CRC16 zvysok po uspesnom CRC16

.equ   MAXUSBBYTES          =14                 ;USB 输入最大的字节数
.equ   MAXRS232LENGTH       =36                 ;RS232 缓冲区长度
.equ   NumberOfFirstBits    =10                 ;kolko prvych bitov moze byt dlhsich
.equ   NoFirstBitsTimerOffset  =256-12800*12/1024 ;定时 12.8ms (12800us 12Mhz:时钟, 1024:定时器分频, 256:定时器溢出值)
.equ   InitBaudRate         =12000000/16/57600-1;UART 波特率57600 (注 12MHz=12000000Hz)
;
;- - - - - - - - - - SRAM定义 - - - - - - - - -
.equ   InputBufferBegin     =RAMEND-127         ;输入数据缓冲区
.equ   InputShiftBufferBegin =InputBufferBegin+MAXUSBBYTES          ;输入移位缓冲区
.equ   RS232BufferBegin     =InputShiftBufferBegin+MAXUSBBYTES      ;RS232 缓冲区

.equ   MyInAddressSRAM      =RS232BufferBegin+MAXRS232LENGTH+1      ;RS232数据输入指针
.equ   MyOutAddressSRAM     =MyInAddressSRAM+1                      ;RS232数据输出指针

.equ   OutputBufferBegin    =RAMEND-MAXUSBBYTES-2      ;USB 输出缓冲区
.equ   AckBufferBegin       =OutputBufferBegin-3       ;USB Ack  缓冲区
.equ   NakBufferBegin       =AckBufferBegin-3          ;USB Nak  缓冲区

.equ   StackBegin           =NakBufferBegin-1          ;堆栈开始位置
;
;- - - - - - - - - 工作寄存器定义 - - - - - - - - -
.def   ConfigByte           =R1         ;目前设备的配置值 没有配置状态=0
.def   backupbitcount       =R2         ;INT0 中备份移位计数器(bitcount)
.def   RAMread              =R3         ;读取数据到RAM的位置
.def   backupSREGTimer      =R4         ;定时器中断中的SREG备份
.def   backupSREG           =R5         ;INT0 中断中的SREG备份
.def   ACC                  =R6         ;累加器(软件模拟的)
.def   lastBitstufNumber    =R7         ;pozicia bitstuffingu
.def   OutBitStuffNumber    =R8         ;kolko bitov sa ma este odvysielat z posledneho bytu - bitstuffing
.def   BitStuffInOut        =R9         ;是增加位填充还是滤除位填充(只使用Bit0 增加=1 滤除=0)
.def   TotalBytesToSend     =R10        ;发送的总字节
.def   TransmitPart         =R11        ;传送的次数
.def   InputBufferLength    =R12        ;dlzka pripravena vo vstupnom USB bufferi
.def   OutputBufferLength   =R13        ;dlzka odpovede pripravena v USB bufferi
.def   MyOutAddress         =R14        ;USB 设备地址(IN)
.def   MyInAddress          =R15        ;USB 设备地址(OUT)


.def   ActionFlag           =R16        ;工作标志
.def   temp3                =R17        ;临时寄存器
.def   temp2                =R18        ;临时寄存器
.def   temp1                =R19        ;临时寄存器
.def   temp0                =R20        ;临时寄存器
.def   bitcount             =R21        ;移位计数器
.def   ByteCount            =R22        ;数据长度
.def   inputbuf             =R23        ;prijimaci 寄存器
.def   shiftbuf             =R24        ;posuvny prijimaci 寄存器
.def   State                =R25        ;工作状态
.def   RS232BufptrX         =R26        ;XL 寄存器 - 用作 prijatych IR kodov 缓冲区指针
.def   RS232BufferFull      =R27        ;XH 寄存器 - priznak plneho RS232 缓冲区
.def   USBBufptrY           =R28        ;YL 寄存器 - 用作 USB 输入/输出缓冲区指针
.def   ROMBufptrZ           =R30        ;ZL 寄存器 - 用作 ROM 缓冲区 dat 指针
;
;- - - - - - - - - USB协议数据定义 - - - - - - -
; USB 规范定义的控制传输的11种标准请求
.equ   GET_STATUS           =0          ;主机请求设备、接口或终端的特性的状态
.equ   CLEAR_FEATURE        =1          ;主机请求使一个设备、接口或终端的一个特性不可用
.equ   SET_FEATURE          =3          ;主机请求使能一个设备、接口或终端
.equ   SET_ADDRESS          =5          ;主机指定以后与设备通讯的地址
.equ   GET_DESCRIPTOR       =6          ;主机请求一个特定的描述符
.equ   SET_DESCRIPTOR       =7          ;主机增加一个描述符或更新一个存在的描述符
.equ   GET_CONFIGURATION    =8          ;主机请求目前设备的配置的值
.equ   SET_CONFIGURATION    =9          ;引导设备使用所选择的配置
.equ   GET_INTERFACE        =10         ;用于具有支持多个接口的配置的设备,主机请求当前的接口号
.equ   SET_INTERFACE        =11         ;用于具有支持多个接口的配置的设备,主机请求一个接口的设置
.equ   SYNCH_FRAME          =12         ;设备设置和报告一个终端的同步帧

;描述符包含的信息的类型
.equ   DEVICE               =1          ;设备
.equ   CONFIGURATION        =2          ;配置
.equ   STRING               =3          ;字符串
.equ   INTERFACE            =4          ;接口
.equ   ENDPOINT             =5          ;终端

.equ   USER_FNC_NUMBER      =100


;------------------------------------------------------------------------------------------
;********************************************************************
;* Interrupt table
;********************************************************************
.cseg
;------------------------------------------------------------------------------------------
.org 0                                  ;复位
       rjmp  reset
;------------------------------------------------------------------------------------------
.org INT0addr                           ;外中断INT0
       rjmp  INT0handler
;
;********************************************************************
;* UART 中断处理
;********************************************************************
.org URXCaddr                           ;UART接收完成
       push  temp0
       in    temp0,UDR                  ;读入异步串行数据到 temp0
       sei                              ;打开中断,为了模拟 USB
       in    backupSREGTimer,SREG       ;保存 SREG
       cbi   UCR,RXCIE                  ;清除 UART 接收完成标志
       cpi   RS232BufferFull,MAXRS232LENGTH-4
       brcc  NoIncRS232BufferFull
       push  RS232BufptrX
       lds   RS232BufptrX,RS232BufferBegin+2  ;取出 RS232 缓冲区指针: 3.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
       st    X+,temp0                   ;将接收到的数据存入缓冲区
       cpi   RS232BufptrX,RS232BufferBegin+MAXRS232LENGTH+1  ;RS232缓冲区是否溢出
       brne  NoUARTBufferOverflow       ;没有溢出
       ldi   RS232BufptrX,RS232BufferBegin+4  ;溢出,重新开始接收
 NoUARTBufferOverflow:
       sts   RS232BufferBegin+2,RS232BufptrX  ;保存 RS232 缓冲区指针: 3.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
       inc   RS232BufferFull            ;增加接收数据计数
       pop   RS232BufptrX
 NoIncRS232BufferFull:
       pop   temp0
       out   SREG,backupSREGTimer       ;恢复 SREG
       cli                              ;

⌨️ 快捷键说明

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