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

📄 avr-2.txt

📁 AVR 下载线源程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
;***************************************************************************
;*
;* Title	: AVR ISP (自动增量地址处理, 19200bps)
;* Version	: 2.1
;* Last	updated	: 2001.7.11
;* Target	: AT90S1200
;* File		: AVR9106.ASM
;*
;* DESCRIPTION
;*	The firmware on	all programmers	now support a unified protocol for
;*	program	and data memory	programming. The host computer do not need
;*	to know	if the programmer operates in serial or	parallel mode.
;*
;*	The following commands are supported. All commands start with a
;*	single letter. The programmer returns 13d (carriage return) or the
;*	data read after	the command is finished.
;*
;*				       +-------------+------------+------+
;*  Commands			       | Host writes | Host reads |	 |
;*  --------			       +-----+-------+------+-----+	 |
;*				       | ID  | data  | data |	  | Note |
;* +-----------------------------------+-----+-------+------+-----+------+
;* | Enter programming mode	       | 'P' |	     |	    | 13d |   1	 |
;* | Set address		       | 'A' | ah al |	    | 13d |   2	 |
;* | Write program memory, low byte    | 'c' |	  dd |	    | 13d |   3	 |
;* | Write program memory, high	byte   | 'C' |	  dd |	    | 13d |   3	 |
;* | Issue Page	Write		       | 'm' |	     |	    | 13d |	 |
;* | Read program memory	       | 'R' |	     |dd(dd)|	  |   4	 |
;* | Write data	memory		       | 'D' |	  dd |	    | 13d |	 |
;* | Read data memory		       | 'd' |	     |	 dd |	  |	 |
;* | Chip erase			       | 'e' |	     |	    | 13d |	 |
;* | Write lock	bits		       | 'l' |	  dd |	    | 13d |	 |
;* | Write fuse	bits		       | 'f' |	  dd |	    | 13d |  11	 |
;* | Read fuse and lock	bits	       | 'F' |	     |	 dd |	  |  11	 |
;* | Leave programming mode	       | 'L' |	     |	    | 13d |   5	 |
;* | Select device type		       | 'T' |	  dd |	    | 13d |   6	 |
;* | Read signature bytes	       | 's' |	     | 3*dd |	  |	 |
;* | Return supported device codes     | 't' |	     | n*dd | 00d |   7	 |
;* | Return software identifier	       | 'S' |	     | s[7] |	  |   8	 |
;* | Return sofware version	       | 'V' |	     |dd dd |	  |   9	 |
;* | Return hardware version	       | 'v' |	     |dd dd |	  |   9	 |
;* | Return programmer type	       | 'p' |	     |	 dd |	  |  10	 |
;* | Set LED			       | 'x' |	  dd |	    | 13d |  12	 |
;* | Clear LED			       | 'y' |	  dd |	    | 13d |  12	 |
;* | Universial	command		       | ':' |	3*dd |	 dd | 13d |  14	 |
;* +-----------------------------------+-----+-------+------+-----+------+
;*
;* NOTE	1
;*	The Enter programming mode command MUST	be sent	one time prior to
;*	the other commands, with the exception of the 't', 'S',	'V', 'v'
;*	and 'T'	commands. The 'T' command must be sent before this command
;*	(see note 6).
;*
;*	For programmers	supporting both	parallel and serial programming
;*	mode this command enters parallel programming mode. For	programmers
;*	supporting only	serial programming mode, this command enters serial
;*	programming mode.
;*
;* NOTE	2
;*	The ah and al are the high and low order bytes of the address. For
;*	parallel programmers this command issues the Load Address Low/High
;*	Byte command. For serial programmers the address byte is stored	for
;*	use by the Read/Write commands.
;*
;* NOTE	3
;*	For parallel programmers this command issues the Program Flash
;*	command. For serial programmers	this command iussues the Write
;*	Program	Memory Command.	For devices with byte-wide program memories
;*	only the low byte command should be used.
;*
;* NOTE	4
;*	The contents of	the program memory at the address given	by the 'A'
;*	command	are written to the serial port in binary form. For byte
;*	wide memories one byte is written. For 16 bit memories two bytes
;*	are written,MSB	first.
;*
;* NOTE	5
;*	离线指令。必须是在编程结束时发出
;*
;* NOTE	6
;*	芯片选择指令。必须在进入编程模式之前发出。
;*
;* NOTE	7
;*	支持芯片代码返回一组以0x00结尾的二进制代码
;*
;* NOTE	8
;*	返回一个7字节ASCII字符串说明编程器类型,在线编程器是"AVR ISP"
;*
;* NOTE	9
;*	返回两字节硬件/软件版本号 ASCII数字
;*
;* NOTE	10
;*	返回所使用编程接口方式类型,对于串行接口的返回'S',并口的'P'.
;*
;* NOTE	11
;*	写熔丝位指令只能对AVR中芯片代码小于0x80并且使用并行编程才有效。
;*	在返回编程器类型的时候不要使用'AVR PPR',这是另外的编程器。
;*
;* NOTE	12
;*	只对AVR开发板才带有发光二极管。对其他的板必须代以NOPs空操作。
;*
;* NOTE	13
;*	当设备欲对FLASH的一页进行页模式编程
;*	Devices	using Page Mode	Programming write one page of flash memory
;*	before issuing a Page Mode Write Pulse.
;*
;* NOTE 14
;*	通用指令。预留给上位电脑控制软件直接与芯片联络使用,以备芯片发展扩充
;*
;***************************************************************************
;本程序主要用于tiny系列下载线的制作,对低频到1M左右的时候仍能够可靠写入。
;注意:编译后将产生两个文件:.hex和.eep请将他们分别写入1200的flash和eeprom.
;你也可以修改一下最后的几段程序,把eeprom这一段东西去掉。
;对其他芯片继续能写,但是速度稍慢,无法两全。         晓奇
;请记得本站的永久网址: http://www.xiao-qi.com/
;**** includes ****

.include "1200def.inc"

.equ	AT89S8252 = 0x86
.equ	AT89S53   = 0x87
.equ	AT90S2313 = 0x20
.equ	AT90S4414 = 0x28
.equ	AT90S8515 = 0x38
.equ	AT90S4433 = 0x30
.equ	AT90S4434 = 0x6C
.equ	AT90s8535 = 0x68
.equ	ATmega103 = 0x41
.equ	ATmega603 = 0x42
.equ	ATmega161 = 0x60
.equ	ATmega163 = 0x64
.equ	ATmega83  = 0x65

.equ	S01838C	= 0x40
.equ	S01838D	= 0x41


;**** Revision Codes ****

.equ	SW_MAJOR = 2		; Major	SW revision number
.equ	SW_MINOR = 1		; Minor	SW revision number
.equ	HW_MAJOR = 1		; Major	HW revision number
.equ	HW_MINOR = 0		; Minor	HW revision number


;***************************************************************************
;*
;* MACROS
;*	Program	Macros
;*
;* DESCRIPTION
;*	Change the following four macros if the	RESET pin to the
;*	target moves and/or if the SCK/MISO/MOSO moves.
;*
;***************************************************************************

.macro	set_reset
	sbi	portb,4
.endm

.macro	clr_reset
	cbi	portb,4
.endm

.macro	ddrd_init
	nop
;	sbi	ddrd,3
.endm

.macro	ddrb_init
	ldi	temp1,0xbf	;bf
	out	ddrb,temp1	; PB6 is input,	the rest is output
.endm

.macro	ddrb_release
	ldi	temp1,0x00
	out	ddrb,temp1	; PB6,rest,pb5,sck is input
;	out	portb,temp1
.endm

.macro	pulse_sck
	sbi	portb,SCK
	nop			;
	nop			;
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	cbi	portb,SCK
	nop
.endm

.macro	pulse_sckr
	sbi	portb,SCK
	nop			;
	nop			;
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	cbi	portb,SCK
.endm


;*****************
;* SPI Constants *
;*****************

.equ	MOSI	= 5		; Bit number on	PORTB
.equ	MISO	= 6		; Bit number on	PORTB
.equ	SCK	= 7		; Bit number on	PORTB


;******************
;* UART	Constants *
;******************

;**** Constant declarations Data Rate ****

;.equ	N = 95			; 115200 BAUD when R=1 and XTAL=11.059MHz
;.equ	N = 31			; 57600	BAUD when R=2 and XTAL=11.059MHz
;.equ	N = 43			; 38400	BAUD when R=2 and XTAL=11.059MHz
;.equ	N = 33			; 19200	BAUD when R=2 and XTAL=4.00MHz
.equ	N = 102			; 38400	BAUD when R=1 and XTAL=4.00MHz
.equ	R = 1

;**** UART transmit pin	in PORTD ****

.equ	TXPIN =	1
.equ	RXPIN =	0		; Receive pin must be external interrupt !!

;**** Bit positions in UART Status Register ****

.equ	TXC = 0			; Transmit
.equ	RXC = 1			; Receive


;*****************************
;* Global Register Variables *
;*****************************
.def	eeaddr	= r18
.def	device	= r16		; Device code
.def	temp1	= r17
.def	temp2	= r18
.def	s_data	= r19		; SPI data
.def	u_data	= r20		; UART data
.def	addrl	= r21		; Low order byte of address
.def	addrh	= r22		; High order byte of address
.def	bit_cnt	= r23		; Bit count used by UART routine
.def	u_stat	= r24		; Status byte used by UART routine
.def	cmd	= r25		; Serial programming command
.def	count	= r26		; Time out variable for	"enter programming mode"
.def	param1	= r27
.def	cmd1	= r28
.def	cmd2	= r29
.def	cmd3	= r30
.def	temp3	= r31

;*********************
;* Interrupt Vectors *
;*********************

.CSEG
	rjmp	RESET		; Reset	Handle
	reti			; IRQ0 Handle (not used)
	rjmp	TIM0_OVF	; Timer0 Overflow Handle
	reti			; Analog Comparator Handle (not	used)


;***************************************************************************
;*
;* INTERRUPT
;*	TIM0_OVF - Software UART Service Routine
;*
;***************************************************************************

TIM0_OVF:
	in	r0,SREG		; store	SREG
	ldi	temp1,(256-N+8)
	out	TCNT0,temp1	; reset	T/C0 to	one bit	lenght
	inc	bit_cnt		; increment bit	counter
	sbrs	u_stat,TXC	; if (transmit complete	flag clear)
	rjmp	transmit	;    goto transmit

to_0:	sec			; set carry
	sbis	PIND,RXPIN	; if (RxD == LOW)
	clc			;	clear carry
	ror	u_data		; shift	carry into u_data

	cpi	bit_cnt,8	; if (bit_cnt == 8)
	brne	to_1		; {
	clr	temp1		;    disable T/C0 Overflow Interrupt
	out	TIMSK,temp1
	sbr	u_stat,1<<RXC	;    set receive complete
to_1:				; }
	out	SREG,r0		; restore SREG
	reti			; exit

transmit:
	cpi	bit_cnt,1	; if (bit_cnt == 1)	\\ start bit
	brne	to_2		; {
	cbi	PORTD,TXPIN	;	generate start bit
	rjmp	to_1		;	exit
to_2:				; }
	cpi	bit_cnt,10	; if (bit_cnt == 10)	\\ stop	bit
	brne	to_3		; {
	sbi	PORTD,TXPIN	;	generate stop bit
	clr	temp1		;	disable	TC0 overflow interrupt
	out	TIMSK,temp1
	sbr	u_stat,1<<TXC	;	set transmit complete bit
	rjmp	to_1		;	exit
to_3:				; }
	sbrc	u_data,0	; if (LSB set)
	sbi	PORTD,TXPIN	;	PD3 = HIGH
	sbrs	u_data,0	; if (LSB clear)
	cbi	PORTD,TXPIN	;	PD3 = LOW
	lsr	u_data		; shift	left u_data
	rjmp	to_1		; exit


;***************************************************************************
;*
;* FUNCTION
;*	u_init
;*
;* DESCRIPTION
;*	Initialize UART.
;*
;***************************************************************************

u_init:	ldi	u_stat,1<<TXC	; set TXC
	ldi	temp1,R		; set clock rate
	out	TCCR0,temp1
	sbi	DDRD,TXPIN	; initialize UART pins
	cbi	DDRD,RXPIN
	ret


;***************************************************************************
;*
;* FUNCTION
;*	putc
;*
;* DESCRIPTION
;*	Send a character on the	UART Tx	line.
;*
;***************************************************************************

putc:	clr	u_stat		; clear	UART status flags
	clr	bit_cnt		; clear	bit counter
	ldi	temp1,1<<TOV0	; enable T/C0 overflow interrupt
	out	TIMSK,temp1
putc0:	sbrs	u_stat,TXC	; while	(!(u_stat & TXC)); // Wait for TXC
	rjmp	putc0
	ret


;***************************************************************************
;*
;* FUNCTION
;*	getc
;*
;* DESCRIPTION
;*	Wait for start bit and receive a character on the UART Rx line.
;*
;***************************************************************************

getc:	sbis	PIND,RXPIN
	rjmp	getc
getc0:	sbic	PIND,RXPIN
	rjmp	getc0
	ldi	temp1,(256-(N+N/2)+8+12);
	out	TCNT0,temp1	; preset T/C0 to 1.5 bit lengths
	ldi	temp1,1<<TOIE0
	out	TIFR,temp1	; clear	T/C0 overflow flag
	out	TIMSK,temp1	; enable T/C0 overflow Interrupt
	clr	bit_cnt		; clear	bit counter
getc1:	sbrs	u_stat,RXC	; wait for Receive Complete
	rjmp	getc1
	cbr	u_stat,1<<RXC	; clear	RXC
	ret


;***************************************************************************
;*
;* FUNCTION
;*	delay
;*
;* DESCRIPTION
;*	 Make a	small delay.
;*
;***************************************************************************

delay:	ldi	temp2,0xff
dl:	dec	temp2
	brne	dl
	dec	temp1
	brne	delay
	ret


;***************************************************************************
;*
;* FUNCTION
;*	wrser
;*
;* DESCRIPTION
;*	 Write a byte to the SPI.
;*
;***************************************************************************

wrser:	ldi	temp1,8
wrs0:	rol	s_data
	brcc	wrs1
	sbi	portb,MOSI
	rjmp	wrs2
wrs1:	cbi	portb,MOSI
wrs2:	pulse_sck
	dec	temp1
	brne	wrs0
	ret


;***************************************************************************
;*
;* FUNCTION
;*	rdser
;*
;* DESCRIPTION
;*	 Read a	byte from the SPI.
;*
;***************************************************************************

rdser:	ldi	temp1,8
	ldi	s_data,0
rd0:	lsl	s_data
	sbic	pinb,MISO
	ori	s_data,1
	pulse_sckr
	dec	temp1
	brne	rd0
	ret


;***************************************************************************
;*
;* FUNCTION
;*	spiinit	(进入编程模式)
;*
;* DESCRIPTION
;*	Initialize SPI interface on AVR	or 'AT89 device.
;*
;***************************************************************************

spiinit:ddrd_init		; initialize port D
	ddrb_init		; initialize port B
	cbi	portb,SCK	; clear	SCK
	tst	device		; if (device !=	AT89S8252)
	brmi	s89		; {
	set_reset		;	set RESET = 1	avr低复位
	ldi	temp1,0xff	;	delay(0xff)49毫秒?
	rcall	delay
	clr_reset		;	set RESET = 0	reset
	rjmp	s0		; }
				; else
s89:				; {			8252高复位
	clr_reset		;	set RESET = 0	sck低了以后
	ldi	temp1,0xff	;	delay(0xff);
	rcall	delay
	set_reset		;	set RESET = 1	reset
s0:				; }
	ldi	temp1,0xff	; delay(0xff);		再延时
	rcall	delay

	ldi	s_data,0xac	; wrser(0xac);		// SPI write (byte 1)
	rcall	wrser
	ldi	s_data,0x53	; wrser(0x53);		// SPI write (byte 2)
	rcall	wrser

				; // SPI Synchronization (fix!)
	cpi	device,0x20	; if ( (device >= 0x20) && (device <= 0x7F) )
	brlo	s2
	tst	device		;是否为零或负(>0x7f)
	brmi	s2		;为负转s2
s0b:				; {
	ldi	count,32	;	count =	32;
s1:				;	do {
	rcall	rdser		;		if (rdser == 0x53)// SPI read (byte 3)
	cpi	s_data,0x53
	breq	s3		;			break;
	ldi	s_data,0x00	;		wrser(0x00);	// SPI write (byte 4)
	rcall	wrser
	pulse_sck		;		pulse SCK
	ldi	s_data,0xac	;		wrser(0xac);	// SPI write (byte 1)
	rcall	wrser
	ldi	s_data,0x53	;		wrser(0x53);	// SPI write (byte 2)
	rcall	wrser
	dec	count		;	} while(--count);
	brne	s1
	rjmp	s3		; }
				; else
s2:				; {
	ldi	s_data,0x00	;	wrser(0x00);		// SPI write (byte3)
	rcall	wrser
s3:				; }
	tst	device		;	 if (device !=	AT89S8252)&&(device !=s53)
	brmi	s4		; {
	ldi	s_data,0x00	;	wrser(0x00);	// SPI write (byte 4)
	rcall	wrser
s4:				; }
	ldi	temp1,0x40	; delay(0x10);
	rcall	delay
	ret



;***************************************************************************
;*
;* FUNCTION
;*	show_id
;*
;* DESCRIPTION
;*	Show our ID ("AVR ISP")	on the serial line.
;*
;***************************************************************************

show_id:ldi	u_data,0x41		; 'A'

⌨️ 快捷键说明

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