?? avr-2.txt
字號:
;***************************************************************************
;*
;* 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 + -