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

📄 avr910.asm

📁 该应用软件可以实现大多数单片机的仿真实验
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;***************************************************************************
;*
;* Title	: AVR ISP (Auto adr inc, 19200bps)
;* Version	: 2.0
;* Last updated	: 1998.01.06 (mlund)
;* Target	: AT90S1200
;* File		: ispprog.asm
;* Author       : Atmel Norway
;*
;* 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 |      |
;* +-----------------------------------+-----+-------+------+-----+------+
;*
;* 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
;*	This command must be executed after the programming is finished.
;*
;* NOTE 6
;*	The select device type command must be sent before the enter
;*	programming command
;*
;* NOTE 7
;*	The supported device codes are returned in binary form terminated
;*	by 0x00.
;*
;* NOTE 8
;*	This return a 7 character ASCII string identifying the programmer.
;*      For the in-system programmer it is "AVR ISP".
;*
;* NOTE 9
;*	The software/hardware version are returned as two ASCII numbers.
;*
;* NOTE 10
;*	This command should be used to identify the programmer type. The
;*	return value is 'S' for serial (or SPI) programmers or 'P' for
;*	parallel programmers.
;*
;* NOTE 11
;*	The write fuse bits command are available only on parallel
;*	programmers and only for AVR devices (device code < 0x80). The host
;*	should use the return programmer type command to determine the
;*	programmer type, do not use the  "AVR PPR" idenifier because other
;*	programmers may be available in the future.
;*
;* NOTE 12
;*	Currently only the AVR development board has LEDs. The other boards
;*	must implement this commands as NOPs.
;*
;* NOTE 13
;*      Devices using Page Mode Programming write one page of flash memory
;*      before issuing a Page Mode Write Pulse.
;***************************************************************************

;**** includes ****

.include "1200def.inc"

;***************************************************************************
;*
;* CONSTANTS
;*	device codes
;*
;* DESCRIPTION
;*	The following device codes must be used by the host computer. Note
;*	that the device codes are arbitrary selected, they do not have any
;*	thing in common with the signature bytes stored in the device.
;*
;*	The following devices are supported (make a new table for each
;*	software release):
;*
;*	SW_MAJOR=1, SW_MINOR=5	
;*	AT90S1200 rev. C (abbreviated S1200C)
;*	AT90S1200 rev. D (abbreviated S1200D)
;*	AT90S8515 rev. A (abbreviated S8515A)
;*	AT89S8252 (abbreviated S8252)
;*
;*	SW_MAJOR=1, SW_MINOR=6
;*	AT90S1200 rev. C (abbreviated S1200C)
;*	AT90S1200 rev. D (abbreviated S1200D)
;*	AT90S8515 rev. A (abbreviated S8515A)
;*	AT89S8252 (abbreviated S8252)
;*      ATmega103 rev. A (abbreviated S01838A)
;*
;***************************************************************************

.equ	S1200C	= 0x12
.equ	S1200D	= 0x13
.equ	S2313A	= 0x20
.equ	S4414A	= 0x28
.equ	S8515A	= 0x38
.equ	S8252	= 0x86
.equ	S2323A	= 0x48

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

;**** Revision Codes ****

.equ	SW_MAJOR = 2		; Major SW revision number
.equ	SW_MINOR = 0		; 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,0xdf
	out	ddrb,temp1	; PB5 is input, the rest is output
.endm

.macro	ddrb_release
	ldi	temp1,(1<<PB4)
	out	ddrb,temp1	; PB4 (RESET) is output, the rest is input
.endm

.macro	pulse_sck
	sbi	portb,SCK
	ldi	temp2,6
m0:	dec	temp2
	brne	m0
	cbi	portb,SCK
	ldi	temp2,1		; 3
m1:	dec	temp2
	brne	m1
.endm


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

.equ	MOSI	= 6		; Bit number on PORTB
.equ	MISO	= 5		; 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 = 2

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

;*********************
;* 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_sck
	dec	temp1
	brne	rd0
	ret


;***************************************************************************
;*
;* FUNCTION
;*	spiinit (Enter programming mode)
;*
;* 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
	cpi	device,S8252	; if (device != S8252)
	breq	s89		; {
	set_reset		;	set RESET = 1
	ldi	temp1,0xff	;	delay(0xff);
	rcall	delay
	clr_reset		;	set RESET = 0
	rjmp	s0		; }
				; else
s89:				; {
	clr_reset		; 	set RESET = 0
	ldi	temp1,0xff	;	delay(0xff);
	rcall	delay
	set_reset		;	set RESET = 1
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
	brmi	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 (byte 3)
	rcall	wrser
s3:				; }
	cpi	device,S8252	; if (device != S8252)
	breq	s4		; {
	ldi	s_data,0x00	;	wrser(0x00);	// SPI write (byte 4)
	rcall	wrser
s4:				; }
	ldi	temp1,0x10	; delay(0x10);
	rcall	delay
	ret


⌨️ 快捷键说明

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