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

📄 main.s

📁 一个AVR单片机BOOTLOADER的例子
💻 S
字号:
	.module main.c
	.area text(rom, con, rel)
	.dbfile C:\mega8\boot\main.c
	.dbfunc e sendchar _sendchar fV
;              c -> R16
	.even
_sendchar::
	.dbline -1
	.dbline 17
; /*******************************************/
; /*            广州天河双龙电子公司         */
; /*            http://www.sl.com.cn         */
; /*           BOOT引导IAP应用演示程序       */
; /*             作者:ntzwq@wx88.net         */
; /*                2002年5月11日            */
; /*   目标MCU:MEGA8   晶振:外部(EXT) 8MHZ   */
; /*******************************************/
; #include "self.h"
; #include "assembly.h"
; #include<iom8v.h>
; #define fosc 8000000 //晶振8MHZ
; #define baud 19200	 //波特率
; extern unsigned char read_flash(unsigned int add);
; /*  		字符输出函数 		 */
; void sendchar(unsigned char c)
; 	{	 
L2:
	.dbline 18
L3:
	.dbline 18
;      while (!(UCSRA&(1<<UDRE)));
	sbis 0xb,5
	rjmp L2
	.dbline 19
; 	 UDR=c;    
	out 0xc,R16
	.dbline -2
	.dbline 20
; 	}
L1:
	.dbline 0 ; func end
	ret
	.dbsym r c 16 c
	.dbend
	.dbfunc e recchar _recchar fc
	.even
_recchar::
	.dbline -1
	.dbline 23
; /*  		字符输入函数 		 */	
; unsigned char recchar(void)
;   	{
L6:
	.dbline 24
L7:
	.dbline 24
; 	 while(!(UCSRA& (1<<RXC)));
	sbis 0xb,7
	rjmp L6
	.dbline 25
;      return UDR;
	in R16,0xc
	.dbline -2
L5:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e uart_init _uart_init fV
	.even
_uart_init::
	.dbline -1
	.dbline 29
; 	}		
; /*			UART初始化				*/	
; void uart_init(void)
; {
	.dbline 30
;  OSCCAL=read_flash(0x1f20);//对内部RC OSC调整
	ldi R16,7968
	ldi R17,31
	rcall _read_flash
	out 0x31,R16
	.dbline 31
;  UCSRB=(1<<RXEN)|(1<<TXEN);//允许发送和接收
	ldi R24,24
	out 0xa,R24
	.dbline 32
;  UBRRL=(fosc/16/(baud+1))%256;
	ldi R24,26
	out 0x9,R24
	.dbline 33
;  UBRRH=(fosc/16/(baud+1))/256;
	clr R2
	out 0x20,R2
	.dbline 34
;  UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8位数据+1位STOP位
	ldi R24,134
	out 0x20,R24
	.dbline -2
	.dbline 35
; }
L9:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e iap _iap fV
;         intval -> R10,R11
;           data -> R14,R15
;          ldata -> R12
;        address -> R22,R23
;            val -> R20
	.even
_iap::
	rcall push_gset5
	.dbline -1
	.dbline 37
; void iap(void)
; {
	.dbline 40
;     unsigned int intval,address,data;
;     unsigned char val, ldata;
;      for(;;)                           
L11:
	.dbline 41
;       {
	.dbline 42
;        val=recchar();         
	rcall _recchar
	mov R20,R16
	.dbline 43
;        if(val=='a')                    //Autoincrement?
	cpi R16,97
	brne L15
	.dbline 44
;           { 
	.dbline 45
; 		   sendchar('Y');				    //Autoincrement is quicker
	ldi R16,89
	rcall _sendchar
	.dbline 46
; 		  }
	rjmp L11
L15:
	.dbline 47
;        else if(val=='A')                   //write address 
	cpi R20,65
	brne L17
	.dbline 48
;           {
	.dbline 49
;            address=recchar();                //read address 8 MSB
	rcall _recchar
	mov R22,R16
	clr R23
	.dbline 50
;            address=(address<<8)|recchar();
	rcall _recchar
	mov R3,R22
	mov R2,R16
	movw R22,R2
	.dbline 51
;            address=address<<1;               //convert from word address to byte address
	lsl R22
	rol R23
	.dbline 52
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 53
;           }
	rjmp L11
L17:
	.dbline 54
;         else if(val=='c')                   //Write program memory, low byte
	cpi R20,99
	brne L19
	.dbline 55
;           {       
	.dbline 56
;            ldata=recchar();
	rcall _recchar
	mov R12,R16
	.dbline 57
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 58
;           }
	rjmp L11
L19:
	.dbline 59
;         else if(val== 'C')                  //Write program memory, high byte 
	cpi R20,67
	brne L21
	.dbline 60
;           {
	.dbline 61
;            data=ldata|(recchar()<<8);
	rcall _recchar
	mov R2,R16
	clr R3
	mov R3,R2
	clr R2
	mov R14,R12
	clr R15
	or R14,R2
	or R15,R3
	.dbline 62
;            fill_temp_buffer(data,(address)); //call asm routine. 
	movw R18,R22
	movw R16,R14
	rcall _fill_temp_buffer
	.dbline 63
;            address+=2;  
	subi R22,254  ; offset = 2
	sbci R23,255
	.dbline 64
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 65
;           }        
	rjmp L11
L21:
	.dbline 66
;          else if(val=='e')                   //Chip erase 
	cpi R20,101
	brne L23
	.dbline 67
;           {
	.dbline 68
;            for(address=0;address < APP_END;address += PAGESIZE)  //Application section = 60 pages
	clr R22
	clr R23
	rjmp L28
L25:
	.dbline 69
	.dbline 70
	ldi R18,3
	movw R16,R22
	rcall _write_page
	.dbline 71
L26:
	.dbline 68
	subi R22,192  ; offset = 64
	sbci R23,255
L28:
	.dbline 68
	cpi R22,0
	ldi R30,28
	cpc R23,R30
	brlo L25
	.dbline 72
;              {
;               write_page(address,0x03);       //Perform page erase
;              }
;            sendchar('\r');        
	ldi R16,13
	rcall _sendchar
	.dbline 73
;           }
	rjmp L11
L23:
	.dbline 74
;          else if(val=='l')                   // write lockbits 
	cpi R20,108
	brne L29
	.dbline 75
;           {
	.dbline 76
;            write_lock_bits(recchar());
	rcall _recchar
	rcall _write_lock_bits
	.dbline 77
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 78
;           }       
	rjmp L11
L29:
	.dbline 79
;          else if(val== 'm')                  // write page
	cpi R20,109
	brne L31
	.dbline 80
;           {
	.dbline 81
;            write_page((address),0x05);       
	ldi R18,5
	movw R16,R22
	rcall _write_page
	.dbline 82
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 83
;           }        
	rjmp L11
L31:
	.dbline 84
;          else if((val=='P')||(val=='L'))     // Enter programming mode 
	cpi R20,80
	breq L35
	cpi R20,76
	brne L33
L35:
	.dbline 85
;           {
	.dbline 86
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 87
;           }
	rjmp L11
L33:
	.dbline 88
;          else if (val=='p')
	cpi R20,112
	brne L36
	.dbline 89
;           {
	.dbline 90
;            sendchar('S');
	ldi R16,83
	rcall _sendchar
	.dbline 91
;           }              
	rjmp L11
L36:
	.dbline 92
;          else if(val=='R')                   //Read program memory 
	cpi R20,82
	brne L38
	.dbline 93
;           {
	.dbline 94
; 		   if (address>=APP_END)
	cpi R22,0
	ldi R30,28
	cpc R23,R30
	brlo L40
	.dbline 95
; 		     {
	.dbline 96
; 			  sendchar(0xff);
	ldi R16,255
	rcall _sendchar
	.dbline 97
; 			  sendchar(0xff);
	ldi R16,255
	rcall _sendchar
	.dbline 98
; 			  address+=2;
	subi R22,254  ; offset = 2
	sbci R23,255
	.dbline 99
; 			 }
	rjmp L11
L40:
	.dbline 101
; 		   else
; 		     {           
	.dbline 102
;               intval=read_program_memory(address,0x00);
	clr R18
	movw R16,R22
	rcall _read_program_memory
	movw R10,R16
	.dbline 103
;               sendchar((char)(intval>>8));      //send MSB  
	mov R16,R17
	clr R17
	rcall _sendchar
	.dbline 104
;               sendchar((char)intval);           //send LSB
	mov R16,R10
	rcall _sendchar
	.dbline 105
;               address+=2;
	subi R22,254  ; offset = 2
	sbci R23,255
	.dbline 106
; 		     }  
	.dbline 107
;           }        
	rjmp L11
L38:
	.dbline 108
;          else if (val == 'D')
	cpi R20,68
	brne L42
	.dbline 109
;           {
	.dbline 110
;            EEARL = address;
	out 0x1e,R22
	.dbline 111
;            EEARH = (address >> 8);
	movw R2,R22
	mov R2,R3
	clr R3
	out 0x1f,R2
	.dbline 112
;            address++;
	subi R22,255  ; offset = 1
	sbci R23,255
	.dbline 113
;            EEDR = recchar();
	rcall _recchar
	out 0x1d,R16
	.dbline 114
;            EECR |= (1<<EEMWE);
	sbi 0x1c,2
	.dbline 115
;            EECR |= (1<<EEWE);
	sbi 0x1c,1
L44:
	.dbline 117
L45:
	.dbline 116
;            while (EECR & (1<<EEWE))
	sbic 0x1c,1
	rjmp L44
	.dbline 118
;               ;
;            sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 119
;            }
	rjmp L11
L42:
	.dbline 120
;           else if (val == 'd')
	cpi R20,100
	brne L47
	.dbline 121
;            {
	.dbline 122
;             EEARL = address;
	out 0x1e,R22
	.dbline 123
;             EEARH = (address >> 8);
	movw R2,R22
	mov R2,R3
	clr R3
	out 0x1f,R2
	.dbline 124
;             address++;
	subi R22,255  ; offset = 1
	sbci R23,255
	.dbline 125
;             EECR |= (1<<EERE);
	sbi 0x1c,0
	.dbline 126
;             sendchar(EEDR);
	in R16,0x1d
	rcall _sendchar
	.dbline 127
;            }       
	rjmp L11
L47:
	.dbline 128
;           else if(val=='F')                   // read fuse bits
	cpi R20,70
	brne L49
	.dbline 129
;            {
	.dbline 130
;             sendchar(read_program_memory(0x0000,0x09));
	ldi R18,9
	clr R16
	clr R17
	rcall _read_program_memory
	rcall _sendchar
	.dbline 131
;            }        
	rjmp L11
L49:
	.dbline 132
;           else if(val=='r')                   // read lock bits
	cpi R20,114
	brne L51
	.dbline 133
;            {
	.dbline 134
;             sendchar(read_program_memory(0x0001,0x09));
	ldi R18,9
	ldi R16,1
	ldi R17,0
	rcall _read_program_memory
	rcall _sendchar
	.dbline 135
;            }        
	rjmp L11
L51:
	.dbline 136
;           else if(val=='N')                   // read high fuse bits
	cpi R20,78
	brne L53
	.dbline 137
;            {
	.dbline 138
;             sendchar(read_program_memory(0x0003,0x09));
	ldi R18,9
	ldi R16,3
	ldi R17,0
	rcall _read_program_memory
	rcall _sendchar
	.dbline 139
;             }        
	rjmp L11
L53:
	.dbline 140
;           else if(val=='t')                   // Return programmer type 
	cpi R20,116
	brne L55
	.dbline 141
;            {
	.dbline 142
;             sendchar(device);
	ldi R16,119
	rcall _sendchar
	.dbline 143
;             sendchar(0);
	clr R16
	rcall _sendchar
	.dbline 144
;             }
	rjmp L11
L55:
	.dbline 145
;           else if ((val=='x')||(val=='y')||(val=='T'))
	cpi R20,120
	breq L60
	cpi R20,121
	breq L60
	cpi R20,84
	brne L57
L60:
	.dbline 146
;             {
	.dbline 147
;              recchar();
	rcall _recchar
	.dbline 148
;              sendchar('\r');
	ldi R16,13
	rcall _sendchar
	.dbline 149
;             }       
	rjmp L11
L57:
	.dbline 150
;           else if (val=='S')                  // Return software identifier 
	cpi R20,83
	brne L61
	.dbline 151
;             {
	.dbline 152
;              sendchar('A');
	ldi R16,65
	rcall _sendchar
	.dbline 153
;              sendchar('V');
	ldi R16,86
	rcall _sendchar
	.dbline 154
;              sendchar('R');
	ldi R16,82
	rcall _sendchar
	.dbline 155
;              sendchar('B');
	ldi R16,66
	rcall _sendchar
	.dbline 156
;              sendchar('O');
	ldi R16,79
	rcall _sendchar
	.dbline 157
;              sendchar('O');
	ldi R16,79
	rcall _sendchar
	.dbline 158
;              sendchar('T');
	ldi R16,84
	rcall _sendchar
	.dbline 159
;             }			                       
	rjmp L11
L61:
	.dbline 160
;           else if (val=='V')                  // Return Software Version
	cpi R20,86
	brne L63
	.dbline 161
;             {
	.dbline 162
;              sendchar('1');
	ldi R16,49
	rcall _sendchar
	.dbline 163
;              sendchar('0');
	ldi R16,48
	rcall _sendchar
	.dbline 164
;              }        
	rjmp L11
L63:
	.dbline 165
;           else if (val=='s')                  // Return Signature Byte
	cpi R20,115
	brne L65
	.dbline 166
;             {							
	.dbline 167
;              sendchar(sig_byte3);
	ldi R16,7
	rcall _sendchar
	.dbline 168
;              sendchar(sig_byte2);
	ldi R16,147
	rcall _sendchar
	.dbline 169
;              sendchar(sig_byte1);
	ldi R16,30
	rcall _sendchar
	.dbline 170
;             }       
	rjmp L11
L65:
	.dbline 171
	cpi R20,27
	brne X1
	rjmp L11
X1:
	.dbline 172
	.dbline 173
	ldi R16,63
	rcall _sendchar
	.dbline 174
	.dbline 175
	.dbline 40
	.dbline 40
	rjmp L11
X0:
	.dbline -2
L10:
	rcall pop_gset5
	.dbline 0 ; func end
	ret
	.dbsym r intval 10 i
	.dbsym r data 14 i
	.dbsym r ldata 12 c
	.dbsym r address 22 i
	.dbsym r val 20 c
	.dbend
	.dbfunc e main _main fV
;        funcptr -> R20,R21
	.even
_main::
	.dbline -1
	.dbline 178
;           else if(val!=0x1b)                  // if not esc
;             {
;              sendchar('?');
;              }
;          }	
; }
; void main(void)
; {
	.dbline 179
;     void (*funcptr)( void ) = 0x0000;       // Set up function pointer
	clr R20
	clr R21
	.dbline 180
; 	DDRD=0;
	clr R2
	out 0x11,R2
	.dbline 181
; 	PORTD=0xff;	
	ldi R24,255
	out 0x12,R24
	.dbline 182
;     uart_init();
	rcall _uart_init
	.dbline 183
; 	if ((PIND&0x04)==0)   
	sbic 0x10,2
	rjmp L70
	.dbline 184
;        {
	.dbline 185
; 	    PORTD=0;
	clr R2
	out 0x12,R2
	.dbline 186
; 	    iap();
	rcall _iap
	.dbline 187
; 	   }
	rjmp L71
L70:
	.dbline 189
	mov R30,R20
	mov R31,R21
	rcall xicall
L71:
	.dbline -2
	.dbline 190
; 	else
; 	   funcptr();   
; }
L69:
	.dbline 0 ; func end
	ret
	.dbsym r funcptr 20 pfV
	.dbend

⌨️ 快捷键说明

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