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

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

📁 AVR309-USB 到 UART 协议转换程序。
💻 TXT
📖 第 1 页 / 共 5 页
字号:
CRC16LoopByte:
       bst   temp1,7                    ;do T uloz MSB zvysku (zvysok je iba 16 bitovy - 8 bit vyssieho byte)
       bld   bitcount,0                 ;do bitcount LSB uloz T - MSB zvysku
       eor   bitcount,temp2             ;XOR bitu spravy a bitu zvysku - v LSB bitcount
       rol   temp0                      ;posun zvysok dolava - nizsi byte (dva byty - cez carry)
       rol   temp1                      ;posun zvysok dolava - vyssi byte (dva byty - cez carry)
       cbr   temp0,1                    ;znuluj LSB zvysku
       lsr   temp2                      ;posun spravu doprava
       ror   bitcount                   ;vysledok XOR-u bitov z LSB do carry
       brcc  CRC16NoXOR                 ;ak je XOR bitu spravy a MSB zvysku = 0 , tak nerob XOR
       ldi   bitcount,CRC16poly>>8      ;do bitcount CRC polynom - vrchny byte
       eor   temp1,bitcount             ;a urob XOR zo zvyskom a CRC polynomom - vrchny byte
       ldi   bitcount,CRC16poly         ;do bitcount CRC polynom - spodny byte
       eor   temp0,bitcount             ;a urob XOR zo zvyskom a CRC polynomom - spodny byte
CRC16NoXOR:
       dec   temp3                      ;boli uz vsetky bity v byte
       brne  CRC16LoopByte              ;ak nie, tak chod na dalsi bit
       cp    USBBufptrY,ByteCount       ;bol uz koniec spravy
       brne  CRC16Loop                  ;ak nie tak opakuj
CRC16End:
       ret                              ;inak skonci (v temp0 a temp1 je vysledok)
;------------------------------------------------------------------------------------------
LoadDescriptorFromROM: ;从 ROM 加载描述符
;从ROM 加载数据到USB 输出缓冲区(用于USB 应答)
       lpm                              ;从 ROM 中取出数据到 r0
       st    Y+,R0                      ;将 R0 的数据存入缓冲区
       adiw  ZH:ZL,1                    ;指向 ROM 的指针加1
       dec   ByteCount                  ;数据加载完成吗?
       brne  LoadDescriptorFromROM      ;接着加载
       rjmp  EndFromRAMROM              ;完成
;------------------------------------------------------------------------------------------
LoadDescriptorFromROMZeroInsert:
;从ROM 加载数据到USB 输出缓冲区(用于USB 应答)但所有偶数字节都添加为0。当一个字符
;串被作为UNICODE 格式请求时(节约ROM)。
       lpm                              ;从ROM中取出数据到R0
       st    Y+,R0                      ;R0 存入到缓冲区

       bst   RAMread,3                  ;Bit3 是否插入一个"0数据"字节
       brtc  InsertingZero              ;Bit3 为 0 ,加载"0数据"字节
       adiw  ZH:ZL,1                    ;指向 ROM 的指针加1
       lpm                              ;从ROM中取出数据到R0
       st    Y+,R0                      ;将 R0 的数据存入缓冲区
       clt                              ;清除 T
       bld   RAMread,3                  ;T 存入RAMread Bit3
       rjmp  InsertingZeroEnd           ;
InsertingZero:
       clr   R0                         ;加载"0数据"字节
       st    Y+,R0                      ;
InsertingZeroEnd:
       adiw  ZH:ZL,1                    ;指向 ROM 的指针加1
       subi  ByteCount,2                ;数据加载完成吗?
       brne  LoadDescriptorFromROMZeroInsert  ;接着加载
       rjmp  EndFromRAMROM              ;完成
;------------------------------------------------------------------------------------------
LoadDescriptorFromSRAM:
;从RAM 加载数据到USB 输出缓冲区(用于USB 应答)
       ld    R0,Z                       ;从RAM中取出数据到 R0
       st    Y+,R0                      ;R0 存入到缓冲区
       inc   ZL                         ;指向下一个 RAM
       dec   ByteCount                  ;能加载的字节数完成吗?
       brne  LoadDescriptorFromSRAM     ;接着取数
       rjmp  EndFromRAMROM              ;完成
;------------------------------------------------------------------------------------------
LoadDescriptorFromEEPROM:
;从EEPROM 加载数据到USB 输出缓冲区(用于USB 应答)。
       out   EEAR,ZL                    ;加载 EEPROM 地址
       sbi   EECR,EERE                  ;允许读 EEPROM
       in    R0,EEDR                    ;读入EEPROM 的内容到 R0
       st    Y+,R0                      ;R0 存入到缓冲区
       inc   ZL                         ;指向下一个 EEPROM
       dec   ByteCount                  ;数据加载完成吗?
       brne  LoadDescriptorFromEEPROM   ;接着加载
       rjmp  EndFromRAMROM              ;完成
;------------------------------------------------------------------------------------------
LoadXXXDescriptor:
;选择回答的源位置:ROM, RAM 或 EEPROM。
       ldi   temp0,SOPbyte              ;加载SOP到输出缓冲区
       sts   OutputBufferBegin,temp0
       ldi   ByteCount,8                ;数据包的大小
       ldi   USBBufptrY,OutputBufferBegin+2   ;Y指针指向发送缓冲区+2

       and   RAMread,RAMread            ;RAMread 是否为0
       brne  FromRAMorEEPROM            ;0=ROM,1=RAM,2=EEPROM,4=ROM(允许插入一个"0数据"字节)
FromROM:
       rjmp  LoadDescriptorFromROM      ;从 ROM 中加载数据
FromRAMorEEPROM:
       sbrc  RAMread,2                  ;RAMread=4
       rjmp  LoadDescriptorFromROMZeroInsert  ;从 ROM 中加载数据
       sbrc  RAMread,0                  ;RAMread=1
       rjmp  LoadDescriptorFromSRAM     ;从 SRAM 中加载数据
       rjmp  LoadDescriptorFromEEPROM   ;从 EEPROM 中加载数据
EndFromRAMROM:
       sbrc  RAMread,7                  ;Bit7=1 表示要求清除 RAMread
       clr   RAMread                    ;清除 RAMread
       rcall ToggleDATAPID              ;切换循环位DATA1/DATA0
       ldi   USBBufptrY,OutputBufferBegin+1   ;加载USB输出缓冲区指针 - 包含 DATA PID
       ret
;------------------------------------------------------------------------------------------
PrepareUSBOutAnswer:  ;在缓冲区中准备输出响应数据
;根据USB 主机的请求在输出缓冲区准备USB 应答,并执行请求的动作。添加位填充到应答中。
       rcall PrepareUSBAnswer           ;根据配置数据进行进一步的处理
MakeOutBitStuff:
       inc   BitStuffInOut              ;增加填充位 增加=1 滤除=0
       ldi   USBBufptrY,OutputBufferBegin  ;给出安排填充位的缓冲区
       rcall BitStuff                      ;安排填充位
       mov   OutputBufferLength,ByteCount  ;获得安排填充位后的数据长度
       clr   BitStuffInOut              ;
       ret
;------------------------------------------------------------------------------------------
PrepareUSBAnswer:  ;在缓冲区中准备应答
;执行请求动作和准备相应回答的主例程。此例程首先判断哪个动作要执行—从输入数据包得到函数
;编号—接着执行函数。函数参数定位于输入数据包。
;例程分为两个大的部分
;1.标准请求
;2.卖主请求(厂家指定的请求)
       clr   RAMread                    ;描述符数据源=ROM
       lds   temp0,InputBufferBegin+2   ;取出 bmRequestType
       lds   temp1,InputBufferBegin+3   ;取出 bRequest
       cbr   temp0,0b10011111           ;保留 bmRequestType 第6位和第5位(请求类型)
       brne  VendorRequest              ;判断是不是卖主请求
       rjmp  StandardRequest            ;00 是 USB 的11种标准请求
;--------------------------
DoSetInfraBufferEmpty:
       rjmp  OneZeroAnswer              ;告诉主机 确认"正确"处理
;--------------------------
DoSetRS232Baud:
       lds   temp0,InputBufferBegin+4   ;取出 RS232 的波特率设置
       out   UBRR,temp0                 ;更改 RS232 的波特率设置
       rjmp  OneZeroAnswer              ;告诉主机 确认"正确"处理
;--------------------------
DoGetRS232Baud:
       in    R0,UBRR                    ;获得当前设备的RS232 的波特率设置到R0
       rjmp  DoGetIn                    ;a ukonci
;--------------------------
DoRS232Send:
       lds   temp0,InputBufferBegin+4   ;取得要发送的 RS232 数据
       out   UDR,temp0                  ;送入 UART
WaitForRS232Send:
       sbis  UCR,TXEN                   ;是否允许 UART 发送数据
       rjmp  OneZeroAnswer              ;回应完成 (AT90S2323/2343没有UART)
       sbis  USR,TXC                    ;发送的数据是否完成
       rjmp  WaitForRS232Send           ;等待RS232发送完成
       rjmp  OneZeroAnswer              ;发送完成,回应主机
;--------------------------
DoRS232Read:
       rjmp  TwoZeroAnswer              ;回应"错误"
;--------------------------
VendorRequest: ;卖主请求
;厂家指定的请求要求能够获得厂家指定的数据(在USB 控制传输中)。这个AVR 设备与主机的
;通信使用USB 控制传输。开发者可以添加他们自己的函数到这里来扩展设备的功能。源代码中不
;同文档的内建函数可以作为添加定制函数的模板使用。
       clr   ZH                         ;由于 RAM 和 EEPROM 只会使用ZL, 所以清除ZH

       cpi   temp1,1                    ;函数名:FNCNumberDoSetInfraBufferEmpty
       breq  DoSetInfraBufferEmpty      ;restartne infra prijimanie (ak bolo zastavene citanim z RAM-ky)

       cpi   temp1,2                    ;函数名:FNCNumberDoGetInfraCode
       breq  DoGetInfraCode             ;vysle prijaty infra kod (ak je v bufferi)

       cpi   temp1,3                    ;函数名:FNCNumberDoSetDataPortDirection
       breq  DoSetDataPortDirection     ;设置I/O口方向
       cpi   temp1,4                    ;函数名:FNCNumberDoGetDataPortDirection
       breq  DoGetDataPortDirection     ;获得I/O口方向

       cpi   temp1,5                    ;函数名:FNCNumberDoSetOutDataPort
       breq  DoSetOutDataPort           ;设置OUT I/O (输出或pull-up数据)
       cpi   temp1,6                    ;函数名:FNCNumberDoGetOutDataPort
       breq  DoGetOutDataPort           ;获得OUT I/O (输出或pull-up数据)

       cpi   temp1,7                    ;函数名:FNCNumberDoGetInDataPort
       breq  DoGetInDataPort            ;获得IN I/O

       cpi   temp1,8                    ;函数名:FNCNumberDoEEPROMRead
       breq  DoEEPROMRead               ;读EEPROM
       cpi   temp1,9                    ;函数名:FNCNumberDoEEPROMWrite
       breq  DoEEPROMWrite              ;写EEPROM

       cpi   temp1,10                   ;函数名:FNCNumberDoRS232Send
       breq  DoRS232Send                ;发送RS232数据
       cpi   temp1,11                   ;函数名:FNCNumberDoRS232Read
       breq  DoRS232Read                ;读入RS232数据

       cpi   temp1,12                   ;函数名:FNCNumberDoSetRS232Baud
       breq  DoSetRS232Baud             ;设置RS232波特率
       cpi   temp1,13                   ;函数名:FNCNumberDoGetRS232Baud
       breq  DoGetRS232Baud             ;获得RS232波特率
       cpi   temp1,14                   ;函数名:FNCNumberDoGetRS232Buffer
       breq  DoGetRS232Buffer           ;获得RS232缓冲区的数据

;15 FNCNumberDoSetRS232DataBits
;16 FNCNumberDoGetRS232DataBits
;17 FNCNumberDoSetRS232Parity
;18 FNCNumberDoGetRS232Parity
;19 FNCNumberDoSetRS232StopBits
;20 FNCNumberDoGetRS232StopBits

       cpi   temp1,USER_FNC_NUMBER+0    ;
       breq  DoUserFunction0            ;用户自定义功能0
       cpi   temp1,USER_FNC_NUMBER+1    ;
       breq  DoUserFunction1            ;用户自定义功能1
       cpi   temp1,USER_FNC_NUMBER+2    ;
       breq  DoUserFunction2            ;用户自定义功能2

       rjmp  ZeroDATA1Answer            ;ak to bolo nieco nezname, tak priprav nulovu odpoved

;-------------------------- 自定义功能 --------------------------

;--------------------------自定义功能的模板----------------------
;------------------ 开始: 这是书写自定义功能的模板 --------------

;能自由使用的寄存器:
    ;temp0,temp1,temp2,temp3,ACC,ZH,ZL
    ;其它寄存器在使用时是被破坏的 (必须使用 push/pop 保存内容)

;在你的程序中必须恰当设置的寄存器:
    ;RAMread - 0=从ROM中读, 1=从RAM中读, 2=从EEPROM中读
    ;temp0 - 发送数据的字节数
    ;ZH,ZL - 指针指向发送数据的缓冲区 (指针指向 ROM/RAM/EEPROM)

;被发送的数据 (准备好数据到缓冲区) :
    ;发送数据必须跳转到 "ComposeEndXXXDescriptor"
    ;发送一个零字节数据必须跳转到 "OneZeroAnswer"  (一般使用为确认"正确"处理)
    ;发送二个零字节数据必须跳转到 "TwoZeroAnswer"  (一般使用为确认"错误"处理)

DoUserFunctionX:
DoUserFunction0:  ;send byte(s) of RAM starting at position given by first parameter in function
       lds   temp0,InputBufferBegin+4   ;prvy  parameter Lo do temp0
       ;lds  temp1,InputBufferBegin+5   ;prvy  parameter Hi do temp1
       ;lds  temp2,InputBufferBegin+6   ;druhy parameter 

⌨️ 快捷键说明

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