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

📄 boot2.asm

📁 Mega8完美下载 包含源程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;***************************************************************************************
;*说明:
;*      1、本程序修改自Avrfreaks的Design Note #032,你可以到 http://www.avrfreaks.com 下载
;*      2、本程序支持 atmega-8 和 AVRProg (版本一定要1.37及以上)。
;*      3、Design Note #032上的程序,是为写的,在上不能正常运行。主要问题是在页写和
;*         擦除以后,不能再重新访问RWW。现在改正了这个bug!
;*      4、请确定你的 AVRProg 的版本在1.37及以上,1.37以下的是不支持 Mega8 的。
;*      5、请用等PonyProg等编程器把编译好的代码(Boot2.hex),写入到Mega8中。
;*         同时编程熔断位:BOOTSZ0 BOOTRST
;*      6、若有问题,请发邮件给我: Zhang_Lei@cnnb.net 。
;*      7、我的主页在 http://avrmcu.topcities.com 。
;***************************************************************************************

;******************** BOOT  LOADER FOR ATmega8 *****************************************
;*
;* File                 : Boot2.asm (Include chip erase counter)
;* Version              : 1.3
;* Compiler             : AVR Studio
;* Target               : ATmega8
;* Output size          : 207 words (414 bytes)
;* Author               : 张磊 ;Email-to: Zhang_Lei@cnnb.net; or zlei@21ic
;*                        website: http://avrmcu.topcities.com
;***************************************************************************************

;****************************************************
;     定义Mega8识别代码、电子标签字节和其它
;****************************************************

.equ    DT      = 0x77  ; Mega8识别代码(Mega8 bootloader)
.equ    SB1     = 0x07  ; 电子标签字节 1
.equ    SB2     = 0x93  ; 电子标签字节 2
.equ    SB3     = 0x1e  ; 电子标签字节 3 
.equ    E2END   = $1FF  ; EEEPROM尾
.equ    UBR     = 12    ; 波特率 = 19.200 bps ,晶振 = 4 MHz。 
                        ;AVRProg 能接受的波特率是 19200 和 115200
.nolist                        
.include "m8def.inc"    ; 包含 mega8 器件配置文件
.list

.CSEG
.org            SECONDBOOTSTART         ;($0F00) 2'nd boot block size is 512

;****************************************************
;  复位并等待AVRProg发送ESC 
;****************************************************
                sbic PIND,PIND4                         ; if (PIND4为0) then 跳到 Boot_Reset
                rjmp $0000                              ;    else 运行用户代码(地址:$0000)

Boot_Reset:

;**** 初识化堆栈
                ldi     R24,low(RAMEND)
                ldi     R25,high(RAMEND)
                out     SPL,R24
                out     SPH,R25                         ; SP = RAMEND
;**** 初识化串口
                ldi     R24,UBR                         ; 波特率 
                out     UBRRL,R24
                ldi     R24,(1<<RXEN)|(1<<TXEN)         ; 使能 TXEN 和 RXEN, 8位
                out     UCSRB,R24                       

L10:            rcall uartGet                           ; repeat (R16 = uartGet)
                cpi R16,27                              ; while (R16 == ESCAPE)
                breq L10
                rjmp    Boot_ID                         ; 若收到ESC,先显示ID,再跳到Boot_Main
                
Boot_Main:      rcall   uartGet                         ; repeat (R16 = uartGet)
                cpi     R16,0x1B                        ; while (R16 == ESCAPE)
                breq    Boot_Main

                cpi     R16,'a'                         ; if(R16=='a') 'a' = Autoincrement?
                brne    L12
                ldi     R16,'Y'                         ; Yes, autoincrement is quicker
                rjmp    L70                             ; uartSend(R16)
                
;*********************************************************************
;  得到地址,并把字节地址(byte address)转换成字地址(word address)的形式
;*********************************************************************

L12:            cpi     R16,'A'                         ; else if(R16=='A') write address
                brne    L14
                rcall   uartGet
                mov     R27,R16                         ; R27 = address high byte
                rcall   uartGet
                mov     R26,R16                         ; R26 = address low byte
                lsl     R26                             ; address=address<<1
                rol     R27                             ; convert from byte address to word address
                rjmp    Send_CR                         ; uartSend('\r')

;****************************************************
; 得到 program data 低字节 
;****************************************************
L14:            cpi     R16,'c'                         ; else if(R16=='c') write program memory, low byte
                brne    L16
                rcall   uartGet
                mov     R22,R16                         ; R22 = data low byte
                rjmp    Send_CR                         ; uartSend('\r')

;****************************************************
;得到 program data 高字节,并把它存入临时缓冲区
;****************************************************
L16:            cpi     R16,'C'                         ;else if(R16=='C') write program memory,high byte
                brne    L18

                rcall   uartGet
                mov     R23,R16                         ; R23 = data high byte

                movw    R30,R26                         ; Z pointer = address
                movw    R0,R22                          ; R0&R1 = data
        
                ldi     R24,1                           ; SPMCR = 0x01
                out     SPMCR,R24                       ; page load (fill temporary buffer)
                spm                                     ; Store program memory

                adiw    R26,2                           ; address=address+2
                rjmp    Send_CR                         ; uartSend('\r')
                
;****************************************************
;  擦除芯片   
;****************************************************

L18:            cpi     R16,'e'                         ; else if(R16=='e') Chip erase
                brne    L28
                
; for(address=0; address < (2*SECONDBOOTSTART); address += (2*PAGESIZE))

                clr     R26                             ; page_erase();
                clr     R27
                rjmp    L24                             ; test for end

L20:            movw    R30,R26                         ; Z-pointer = address
                ldi     R24,3                           ; SPMCR = 0x03
                out     SPMCR,R24                       ; page_erase
                spm                                     ; Store program memory
                                                ; do the page erase
                rcall   wait_spm                        ; wait for done
        
                subi    R26,low(-2*PAGESIZE)            ; address += (2*PAGESIZE)
                sbci    R27,high(-2*PAGESIZE)

L24:            ldi     R24,low(2*SECONDBOOTSTART)
                ldi     R25,high(2*SECONDBOOTSTART)
                cp      R26,R24                         ; address < Boot Flash address(byte address) 0x3E00 ?
                cpc     R27,R25
                brlo    L20
        
                ldi     R26,low(E2END-1)                ; increment Chip Erase Counter located at address E2END-1
                ldi     R27,high(E2END-1)               ; 
                movw    R22,R26                         ; Save Chip Erase Counter Address in R22
                ldi     R17,1                           ; read EEPROM
                rcall   EepromTalk
                mov     R24,R16                         ; R24 = Chip Erase Counter low byte
                rcall   EepromTalk
                mov     R25,R16                         ; R25 = Chip Erase Counter high byte
                adiw    R24,1                           ; counter ++
                out     EEDR,R24                        ; EEDR = R24 Chip Erase Counter low byte
                movw    R26,R22                         ; R26 = Chip Erase Counter Address
                ldi     R17,6                           ; write EEPROM
                rcall   EepromTalk
                out     EEDR,R25                        ; EEDR = R25 Chip Erase Counter high byte
                rcall   EepromTalk

                rjmp    Send_CR                         ; uartSend('\r')

;****************************************************
;  页写( page write)
;****************************************************
L28:            cpi     R16,'m'                         ; else if(R16== 'm') Write page
                brne    L34
                movw    R30,R26                         ; Z-pointer = address
                ldi     R24,5                           ; SPMCR = 0x05 Write page
                out     SPMCR,R24
                spm                                     ; Store program memory
                rcall   wait_spm
L32:            rjmp    Send_CR                         ; uartSend('\r')
                                

;****************************************************
;* 进入编程模式
;****************************************************
L34:            cpi     R16,'P'                         ; else if(R16=='P') Enter programming mode
                breq    L32                             ; uartSend('\r')
                cpi     R16,'L'                         ; else if(R16=='L') Leave programming mode
                breq    L32                             ; uartSend('\r')

;********************************************************
;返回所使用编程接口方式类型,对于串行接口的返回'S',并口的'P'.
;********************************************************
                cpi     R16,'p'                         ; else if (R16=='p') Return programmer type
                brne    L38

                ldi     R16,'S'                         ; uartSend('S') Serial
                rjmp    L70                             ; uartSend(R16)

;****************************************************

⌨️ 快捷键说明

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