📄 avrbootloader.lst
字号:
(0192) /* 字符输入函数 */
(0193) unsigned char RecChar(void)
(0194) {
(0195) while(!(UCSRA & 0x80));
_RecChar:
CEC 9B5F SBIS 0x0B,7
CED CFFE RJMP _RecChar
(0196) return UDR;
CEE B10C IN R16,0x0C
CEF 9508 RET
(0197) }
(0198) /*****************************************************************************/
(0199) void SendChar(unsigned char c)
(0200) {
(0201) while (!(UCSRA&(1<<UDRE)));
_SendChar:
c --> R16
CF0 9B5D SBIS 0x0B,5
CF1 CFFE RJMP _SendChar
(0202) UDR=c;
CF2 B90C OUT 0x0C,R16
CF3 9508 RET
(0203) }
(0204) void delay(void)
(0205) {
(0206) unsigned int i;
(0207) for (i=0;i<65530;i++);
_delay:
i --> R16
CF4 2700 CLR R16
CF5 2711 CLR R17
CF6 C002 RJMP 0x0CF9
CF7 5F0F SUBI R16,0xFF
CF8 4F1F SBCI R17,0xFF
CF9 EF8A LDI R24,0xFA
CFA EF9F LDI R25,0xFF
CFB E0A0 LDI R26,0
CFC E0B0 LDI R27,0
CFD 0118 MOVW R2,R16
CFE 2444 CLR R4
CFF 2455 CLR R5
D00 1628 CP R2,R24
D01 0639 CPC R3,R25
D02 064A CPC R4,R26
D03 065B CPC R5,R27
D04 F394 BLT 0x0CF7
D05 9508 RET
(0208) }
(0209)
(0210) /*****************************************************************************/
(0211) void ExecCode(void)
(0212) {
(0213) GICR=0X01; //中断向量表移位允许
_ExecCode:
D06 E081 LDI R24,1
D07 BF8B OUT 0x3B,R24
(0214) GICR=0X00; //中断向量指向应用程序区
D08 2422 CLR R2
D09 BE2B OUT 0x3B,R2
(0215) asm("jmp 0x0000");
D0A 940C 0000 JMP 0x0000
D0C 9508 RET
(0216) }
(0217) //UART0 initialize
(0218) // desired baud rate: 9600
(0219) // actual: baud rate:9615 (0.2%)
(0220) void uart0_init(void)
(0221) {
(0222) UCSRB = 0x00; //disable while setting baud rate
_uart0_init:
D0D 2422 CLR R2
D0E B82A OUT 0x0A,R2
(0223) UCSRA = 0x02;
D0F E082 LDI R24,2
D10 B98B OUT 0x0B,R24
(0224) UCSRC = BIT(URSEL) | 0x06;
D11 E886 LDI R24,0x86
D12 BD80 OUT 0x20,R24
(0225) UBRRL = 0x0C; //set baud rate lo
D13 E08C LDI R24,0xC
D14 B989 OUT 0x09,R24
(0226) UBRRH = 0x00; //set baud rate hi
D15 BC20 OUT 0x20,R2
(0227) UCSRB = 0x18;
D16 E188 LDI R24,0x18
D17 B98A OUT 0x0A,R24
D18 9508 RET
(0228) }
(0229) void main(void)
(0230) {
(0231) unsigned char BootFlag;
(0232) unsigned int TempInt;
(0233) char iTry;
(0234) CLI();
_main:
iTry --> R20
TempInt --> R22
BootFlag --> R22
D19 94F8 BCLR 7
(0235) #ifdef InteClk //如果使用内部时钟,读取时钟校准值
(0236) OSCCAL=read_flash(OscAddress);
(0237) #endif
(0238)
(0239) #ifdef W0
(0240) //pei 拷贝W0的PortInit
(0241) PORTB = 0x0F;//rfslp,fs123=1
D1A E08F LDI R24,0xF
D1B BB88 OUT 0x18,R24
(0242) DDRB = 0xFF;//bit1=output
D1C EF8F LDI R24,0xFF
D1D BB87 OUT 0x17,R24
(0243) PORTC = 0x21;//0x20;//rfrst=1,not reset!
D1E E281 LDI R24,0x21
D1F BB85 OUT 0x15,R24
(0244) DDRC = 0x7F;
D20 E78F LDI R24,0x7F
D21 BB84 OUT 0x14,R24
(0245) PORTD = 0x0C;
D22 E08C LDI R24,0xC
D23 BB82 OUT 0x12,R24
(0246) DDRD = 0xF0;
D24 EF80 LDI R24,0xF0
D25 BB81 OUT 0x11,R24
(0247) #else
(0248) #endif
(0249)
(0250) //UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位数据+1位停止
(0251) //UCSRB = (1<<RXEN)|(1<<TXEN); //允许串口发送和接收
(0252) //UBRR = BAU;
(0253) UCSRB = 0x00; //disable while setting baud rate
D26 2422 CLR R2
D27 B82A OUT 0x0A,R2
(0254) UCSRA = 0x02;
D28 E082 LDI R24,2
D29 B98B OUT 0x0B,R24
(0255) UCSRC = BIT(URSEL) | 0x06;
D2A E886 LDI R24,0x86
D2B BD80 OUT 0x20,R24
(0256) UBRRL = 0x0C; //set baud rate lo
D2C E08C LDI R24,0xC
D2D B989 OUT 0x09,R24
(0257) UBRRH = 0x00; //set baud rate hi
D2E BC20 OUT 0x20,R2
(0258) UCSRB = 0x18;
D2F E188 LDI R24,0x18
D30 B98A OUT 0x0A,R24
(0259) iTry=20;
D31 E144 LDI R20,0x14
(0260) STARTBOOT://pei未下载程序时重复等待
(0261) #ifdef W0
(0262) PORTC=PORTC^0x03;//指示灯闪烁
D32 E083 LDI R24,3
D33 B225 IN R2,0x15
D34 2628 EOR R2,R24
D35 BA25 OUT 0x15,R2
(0263) #endif
(0264) delay(); //延时等待PC机响应
D36 DFBD RCALL _delay
(0265) delay(); //延时等待PC机响应
D37 DFBC RCALL _delay
(0266) delay(); //延时等待PC机响应
D38 DFBB RCALL _delay
(0267) SendChar('>'); //通知PC机,BOOT下载准备就绪
D39 E30E LDI R16,0x3E
D3A DFB5 RCALL _SendChar
(0268) delay(); //延时等待PC机响应
D3B DFB8 RCALL _delay
(0269) delay(); //延时等待PC机响应
D3C DFB7 RCALL _delay
(0270) delay(); //延时等待PC机响应
D3D DFB6 RCALL _delay
(0271) BootFlag=UDR;
D3E B16C IN R22,0x0C
(0272)
(0273) if (BootFlag == '<')
D3F 336C CPI R22,0x3C
D40 F4E9 BNE 0x0D5E
(0274) {
(0275) SendChar(ChipType); //芯片版本信息
D41 E300 LDI R16,0x30
D42 DFAD RCALL _SendChar
(0276) SendChar(BootSize);
D43 E603 LDI R16,0x63
D44 DFAB RCALL _SendChar
(0277) SendChar(BootVer);
D45 E607 LDI R16,0x67
D46 DFA9 RCALL _SendChar
D47 C015 RJMP 0x0D5D
(0278) while (1)
(0279) {
(0280) switch (RecChar())
D48 DFA3 RCALL _RecChar
D49 2F60 MOV R22,R16
D4A 2777 CLR R23
D4B 3465 CPI R22,0x45
D4C E0E0 LDI R30,0
D4D 077E CPC R23,R30
D4E F059 BEQ 0x0D5A
D4F 3465 CPI R22,0x45
D50 E0E0 LDI R30,0
D51 077E CPC R23,R30
D52 F054 BLT 0x0D5D
D53 3567 CPI R22,0x57
D54 E0E0 LDI R30,0
D55 077E CPC R23,R30
D56 F009 BEQ 0x0D58
D57 C005 RJMP 0x0D5D
(0281) {
(0282) case 'W': FlashLoad();
D58 DEE0 RCALL _FlashLoad
(0283) break;
D59 C003 RJMP 0x0D5D
(0284) case 'E': {
(0285) SendChar('E'); //通知PC机,进入运用程序区
D5A E405 LDI R16,0x45
D5B DF94 RCALL _SendChar
(0286) ExecCode();
D5C DFA9 RCALL _ExecCode
D5D CFEA RJMP 0x0D48
(0287) } break;
(0288) default : break;
(0289) }
(0290) }
(0291) }
(0292) SendChar('E');
D5E E405 LDI R16,0x45
D5F DF90 RCALL _SendChar
(0293)
(0294) TempInt = read_program_memory(0,0);//pei
D60 2722 CLR R18
D61 2700 CLR R16
D62 2711 CLR R17
D63 D021 RCALL _read_program_memory
D64 01B8 MOVW R22,R16
(0295) if (TempInt==0xFFFF) goto STARTBOOT;
D65 3F0F CPI R16,0xFF
D66 EFEF LDI R30,0xFF
D67 071E CPC R17,R30
D68 F409 BNE 0x0D6A
D69 CFC8 RJMP 0x0D32
(0296) else{ iTry--;
D6A 954A DEC R20
(0297) if (iTry>0) goto STARTBOOT;}
D6B E080 LDI R24,0
D6C 1784 CP R24,R20
D6D F408 BCC 0x0D6F
D6E CFC3 RJMP 0x0D32
(0298) SEI();
D6F 9478 BSET 7
(0299) ExecCode();//执行用户区程序
D70 DF95 RCALL _ExecCode
D71 9508 RET
FILE: F:\AVR常用函数\BootLooderMage8\BootLoad_1M\assembly.s
(0001) .text
(0002)
(0003) SPMCR = 0x57 ;RWW区忙标志,读RWW区允许,允许写程序存储区
(0004)
(0005) ; void write_page (unsigned int adr, unsigned char function);
(0006) ; bits 8:15 adr addresses the page...(must setup RAMPZ beforehand!!!)
(0007) _write_page::
(0008) XCALL __WAIT_SPMEN__
_write_page:
D72 D01F RCALL 0x0D92
(0009) movw r30, r16 ;move address to z pointer (R31 = ZH, R30 = ZL)
D73 01F8 MOVW R30,R16
(0010) STS SPMCR, R18 ;argument 2 decides function
D74 9320 0057 STS 0x0057,R18
(0011) SPM ;perform pagewrite
D76 95E8 SPM
(0012) RET
D77 9508 RET
(0013)
(0014) ;-----------------------------------------
(0015)
(0016) ; void fill_temp_buffer (unsigned int data, unsigned int adr);
(0017) ; bits 7:1 in adr addresses the word in the page... (2=first word, 4=second word etc..)
(0018) _fill_temp_buffer::
(0019) XCALL __WAIT_SPMEN__
_fill_temp_buffer:
D78 D019 RCALL 0x0D92
(0020) movw r30, r18 ;move adress to z pointer (R31=ZH R30=ZL)
D79 01F9 MOVW R30,R18
(0021) movw r0, r16 ;move data to reg 0 and 1
D7A 0108 MOVW R0,R16
(0022) LDI R19, 0x01
D7B E031 LDI R19,1
(0023) STS SPMCR, R19
D7C 9330 0057 STS 0x0057,R19
(0024) SPM ;Store program memory
D7E 95E8 SPM
(0025) RET
D7F 9508 RET
(0026)
(0027) ;-----------------------------------------
(0028)
(0029) ;unsigned char read_flash(unsigned int add);
(0030) _read_flash::
(0031) mov r31,r17
_read_flash:
D80 2FF1 MOV R31,R17
(0032) mov r30,r16
D81 2FE0 MOV R30,R16
(0033) lpm r16,z
D82 9104 LPM R16,87(Z)
(0034) clr r17
D83 2711 CLR R17
(0035) ret
D84 9508 RET
(0036)
(0037) ;unsigned int read_program_memory (unsigned int adr ,unsigned char cmd);
(0038) _read_program_memory::
(0039) movw r30, r16 ;move adress to z pointer
_read_program_memory:
D85 01F8 MOVW R30,R16
(0040) SBRC R18, 0 ;read lockbits? (second argument = 0x09)
D86 FD20 SBRC R18,0
(0041) STS SPMCR, R18 ;if so, place second argument in SPMEN register
D87 9320 0057 STS 0x0057,R18
(0042) LPM r16, Z+
D89 9105 LPM R16,Z+
(0043) LPM r17, Z
D8A 9114 LPM R17,87(Z)
(0044) RET
D8B 9508 RET
(0045)
(0046) ;-----------------------------------------
(0047)
(0048) _enableRWW::
(0049) XCALL __WAIT_SPMEN__
_enableRWW:
D8C D005 RCALL 0x0D92
(0050) LDI R27,0x11
D8D E1B1 LDI R27,0x11
(0051) STS SPMCR,R27
D8E 93B0 0057 STS 0x0057,R27
(0052) SPM
D90 95E8 SPM
(0053) RET
D91 9508 RET
(0054)
(0055) ;-----------------------------------------
(0056)
(0057) __WAIT_SPMEN__:
(0058) LDS R27,SPMCR ; load SPMCR to R27
D92 91B0 0057 LDS R27,0x0057
(0059) SBRC R27,0 ; check SPMEN flag
D94 FDB0 SBRC R27,0
(0060) RJMP __WAIT_SPMEN__ ; wait for SPMEN flag cleared
D95 CFFC RJMP 0x0D92
(0061) RET
FILE: <library>
D96 9508 RET
pop_xgset30FC:
D97 90A9 LD R10,Y+
D98 90B9 LD R11,Y+
D99 90C9 LD R12,Y+
D9A 90D9 LD R13,Y+
D9B 90E9 LD R14,Y+
D9C 90F9 LD R15,Y+
D9D 9149 LD R20,Y+
D9E 9159 LD R21,Y+
D9F 9508 RET
push_xgsetF0FC:
DA0 937A ST R23,-Y
DA1 936A ST R22,-Y
push_xgset30FC:
DA2 935A ST R21,-Y
DA3 934A ST R20,-Y
push_xgset00FC:
DA4 92FA ST R15,-Y
DA5 92EA ST R14,-Y
push_xgset003C:
DA6 92DA ST R13,-Y
DA7 92CA ST R12,-Y
DA8 92BA ST R11,-Y
DA9 92AA ST R10,-Y
DAA 9508 RET
push_xgset300C:
DAB 935A ST R21,-Y
DAC 934A ST R20,-Y
DAD 92BA ST R11,-Y
DAE 92AA ST R10,-Y
DAF 9508 RET
pop_xgset300C:
DB0 90A9 LD R10,Y+
DB1 90B9 LD R11,Y+
DB2 9149 LD R20,Y+
DB3 9159 LD R21,Y+
DB4 9508 RET
push_xgset303C:
DB5 935A ST R21,-Y
DB6 934A ST R20,-Y
DB7 92DA ST R13,-Y
DB8 92CA ST R12,-Y
DB9 92BA ST R11,-Y
DBA 92AA ST R10,-Y
DBB 9508 RET
pop_xgset303C:
DBC 90A9 LD R10,Y+
DBD 90B9 LD R11,Y+
DBE 90C9 LD R12,Y+
DBF 90D9 LD R13,Y+
DC0 9149 LD R20,Y+
DC1 9159 LD R21,Y+
DC2 9508 RET
lsl16:
DC3 2322 TST R18
DC4 F021 BEQ 0x0DC9
DC5 0F00 LSL R16
DC6 1F11 ROL R17
DC7 952A DEC R18
DC8 CFFA RJMP lsl16
DC9 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -