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

📄 boot2_dn.asm

📁 Mega8完美下载 包含源程序
💻 ASM
字号:

;*************** BOOT  LOADER FOR ATmega163 ***********************
;*
;* File 		: AVRBoot2.asm (Include chip erase counter)
;* Version 		: 1.2
;* Compiler		: AVR Studio
;* Target		: ATmega163
;* Output size 		: 392 bytes
;*
;******************************************************************

.equ DT 	= 0x66 		; Device Type = 0x66 (ATmega163)
.equ SB1 	= 0x02 		; Signature byte 1
.equ SB2 	= 0x94 		; Signature byte 2
.equ SB3 	= 0x1e 		; Signature byte 3
.equ UBR 	= 25 		; Baud rate = 19.200 bps with fCK = 4 MHz

.INCLUDE "m163def.inc" 		;Include Register/Bit Definitions for the mega163

.org SECONDBOOTSTART 		; ($1F00) second boot. Block size is 512B

	sbic PINC,PINC0 	; Skip next instruction if PINC0 cleared
	rjmp FLASHEND+1 	; else normal execution from Reset (FLASHEND+1 = Address 0000)

; Programming mode
	
	ldi R24,low(RAMEND)
	ldi R25,high(RAMEND)
	out SPL,R24
	out SPH,R25 		; SP = RAMEND
	
	ldi R24,UBR 		; Baud rate = 19.200 bps
	out UBRR,R24
	ldi R24,(1<<RXEN)|(1<<TXEN)
	out UCSRB,R24 		; Enable receiver & transmitter, 8-bit mode

L10: 	rcall uartGet 		; repeat (R16 = uartGet)
	cpi R16,27 		; while (R16 == ESCAPE)
	breq L10
	
	cpi R16,'a' 		; if(R16==’a’) ’a’ = Autoincrement?
	brne L12
	ldi R16,'Y' 		; Yes, autoincrement is quicker
	rjmp L70 		; uartSend(R16)

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 L68 		; uartSend(’\r’)

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 L68 		; uartSend(’\r’)

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 L68 		; 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

L20: 	movw R30,R26 		; Z-pointer = address
	ldi R24,3 		; SPMCR = 0x03
	out SPMCR,R24 		; page_erase
	spm 			; Store program memory
	nop
	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
	ldi R27,high(E2END-1) 	; at address 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 L68 		; uartSend(’\r’)
	
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
	nop

L32: 	rjmp L68 		; 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’)
	cpi R16,'p' 		; else if (R16==’p’) Return programmer type
	brne L38
	ldi R16,'S' 		; uartSend(’S’) Serial
	rjmp L70 		; uartSend(R16)

L38: 	cpi R16,'R' 		; else if(R16==’R’) Read program memory
	brne L40
	movw R30,R26 		; Z-pointer <= address
	lpm R24,Z+ 		; read program memory LSB; store LSB in R24 and Z pointer ++
	lpm R16,Z+ 		; read program memory MSB; store MSB in R16 and Z pointer ++
	rcall uartSend 		; uartSend(R16) MSB
	movw R26,R30 		; address += 2
	mov R16,R24 		; LSB stored in R16
	rjmp L70 		; uartSend(R16) LSB

L40: 	cpi R16,'D'		; else if (R16==’D’) Write data to EEPROM
	brne L42
	rcall uartGet
	out EEDR,R16 		; EEDR = uartGet()
	ldi R17,6 		; write EEPROM
	rcall EepromTalk
	rjmp L68 		; uartSend(’\r’)

L42: 	cpi R16,'d' 		; else if (R16==’d’) Read data from EEPROM
	brne L44
	ldi R17,1 		; read EEPROM
	rcall EepromTalk 	; R16 = EEPROM data
	rjmp L70 		; uartSend(R16)

L44: 	cpi R16,'F' 		; else if(R16==’F’) Read fuse bits
	brne L46
	clr R30 		; Z-pointer = 0000
	rjmp L50 		; rcall readFuseAndLock

L46: 	cpi R16,'r' 		; else if(R16==’r’) Read lock bits
	brne L48
	ldi R30,1 		; Z pointer = 0001
	rjmp L50 		; rcall readFuseAndLock

L48: 	cpi R16,'N' 		; else if(R16==’N’) Read high fuse bits
	brne L52
	ldi R30,3 		; Z-pointer = 0003

L50: 	rcall readFuseAndLock
	rjmp L70 		; uartSend(R16)

L52: 	cpi R16,'t' 		; else if(R16==’t’) Return supported devices code
	brne L54
	ldi R16,DT 		; Device Type
	rcall uartSend 		; uartSend(DT) send Device Type
	clr R16
	rjmp L70 		; uartSend(0)

L54: 				; else if ((R16==’l’)||(R16==’x’)||(R16==’y’)||(R16==’T’))
	cpi R16,'l' 		; ’l’ = Write Boot Loader lockbits
	breq L56
	cpi R16,'x' 		; ’x’ = Set LED
	breq L56
	cpi R16,'y' 		; ’y’ = Clear LED
	breq L56
	cpi R16,'T' 		; ’T’ = Select device type
	brne L60

L56: 	rcall uartGet 		; R16 = uartGet()
	; YOU CAN INSERT LEDs CODE HERE
	rjmp L68 		; uartSend(’\r’)
	L60: cpi R16,'S' 	; else if (R16==’S’) Return software identifier
	brne L62
	ldi R30,low(2*Soft_Id)
	ldi R31,high(2*Soft_Id)
L61: 	lpm R16,Z+
	tst R16
	breq L72 		; branch is end of string ((Z) == 0)
	rcall uartSend 		; else send char
	rjmp L61

L62: 	cpi R16,'V' 		; else if (R16==’V’) Return Software Version
	brne L64
	ldi R16,'1' 		; uartSend(’1’)
	rcall uartSend
	ldi R16,'2' 		; uartSend(’2’)
	rjmp L70 		; uartSend(R16)

L64: 	cpi R16,'s' 		; else if (R16==’s’) Return Signature Byte
	brne L66
	ldi R16,SB1 		; uartSend(SB1) Signature Byte 1
	rcall uartSend
	ldi R16,SB2 		; uartSend(SB2) Signature Byte 2
	rcall uartSend
	ldi R16,SB3 		; uartSend(SB3) Signature Byte 3
	rjmp L70 		; uartSend(R16)
	
L66: 	ldi R16,'?' 		; else uartSend(’?’)
	rjmp L70 		; uartSend(R16)
L68: 	ldi R16,13 		; uartSend(’\r’)
L70: 	rcall uartSend 		; uartSend(R16)
L72: 	rjmp L10

readFuseAndLock:
	clr R31 		; Z pointer high byte = 0
	ldi R24,9 		; SPMCR = 0x09
	out SPMCR,R24 		; read fuse and lock
	lpm R16,Z 		; read program memory
	ret

EepromTalk: 			; if R17 == 6 then Write, if R17 == 1 then Read
	out EEARL,R26 		; EEARL = address low
	out EEARH,R27		; EEARH = address high
	adiw R26,1 		; address++
	sbrc R17,1 		; skip if R17 == 1 (read Eeprom)
	sbi EECR,EEMWE 		; EEMWE = 1 (write Eeprom)
	out EECR,R17 		; EECR = R17 (6 write, 1 read)

L90: 	sbic EECR,EEWE 		; wait until EEWE == 0
	rjmp L90
	in R16,EEDR 		; R16 = EEDR
	ret

uartSend: 			; send R16
	sbis UCSRA,UDRE 	; wait for empty transmit buffer (until UDRE==1)
	rjmp uartSend
	out UDR,R16 		; UDR = R16, start transmission
	ret

uartGet:
	sbis UCSRA,RXC 		; wait for incoming data (until RXC==1)
	rjmp uartGet
	in R16,UDR 		; return received data in R16
	ret

Soft_Id: 
	.DB "AVRBL8", 0
	
; END of BOOT LOADER PROGRAM

⌨️ 快捷键说明

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