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

📄 51.lst

📁 笔者的《用M8L制作的89S51单片机 USB下载线》在无线电2007年第9期已刊登过
💻 LST
📖 第 1 页 / 共 3 页
字号:
__text_start:
__start:
    001A E5CF      LDI	R28,0x5F
    001B E0D4      LDI	R29,4
    001C BFCD      OUT	0x3D,R28
    001D BFDE      OUT	0x3E,R29
    001E 51C0      SUBI	R28,0x10
    001F 40D0      SBCI	R29,0
    0020 EA0A      LDI	R16,0xAA
    0021 8308      STD	Y+0,R16
    0022 2400      CLR	R0
    0023 E6E0      LDI	R30,0x60
    0024 E0F0      LDI	R31,0
    0025 E010      LDI	R17,0
    0026 38EC      CPI	R30,0x8C
    0027 07F1      CPC	R31,R17
    0028 F011      BEQ	0x002B
    0029 9201      ST	R0,Z+
    002A CFFB      RJMP	0x0026
    002B 8300      STD	Z+0,R16
    002C E3E4      LDI	R30,0x34
    002D E0F0      LDI	R31,0
    002E E6A0      LDI	R26,0x60
    002F E0B0      LDI	R27,0
    0030 E010      LDI	R17,0
    0031 33E4      CPI	R30,0x34
    0032 07F1      CPC	R31,R17
    0033 F021      BEQ	0x0038
    0034 95C8      LPM
    0035 9631      ADIW	R30,1
    0036 920D      ST	R0,X+
    0037 CFF9      RJMP	0x0031
    0038 D2A8      RCALL	_main
_exit:
    0039 CFFF      RJMP	_exit
_SendInstrc:
  n                    --> R20
  nByte                --> R16
    003A D306      RCALL	push_gset1
FILE: E:\学习专区\AVR专区\个人创作区\ICC\s51.c
(0001) ///////////////////////////////////////////////////////////////////////////////////////////////////
(0002) //FID=02:AT89S51系列编程器 
(0003) //实现编程的读,写,擦等细节
(0004) ///////////////////////////////////////////////////////////////////////////////////////////////////
(0005) #include <iom8v.h>
(0006) #include <macros.h>
(0007) #include<signal.h>
(0008) #include<e51pro.h>
(0009) #define uchar unsigned char 
(0010) BYTE OutBuf[4];//发送命令缓冲
(0011) BYTE InBuf[4];//接收缓冲
(0012) void SendInstrc(uchar nByte)//用MOSI串行发送命令的同时用MISO接收相关数据
(0013) {
(0014) uchar n=0;
    003B 2744      CLR	R20
(0015) DDRB=(1<<PB5)|(1<<PB3)|(1<<PB2);
    003C E28C      LDI	R24,0x2C
    003D BB87      OUT	0x17,R24
(0016) SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);//SCK时钟为fosc/16
    003E E581      LDI	R24,0x51
    003F B98D      OUT	0x0D,R24
(0017) for (n=0;n<nByte;n++)
    0040 C013      RJMP	0x0054
(0018) {
(0019) SPDR=OutBuf[n];
    0041 E684      LDI	R24,0x64
    0042 E090      LDI	R25,0
    0043 2FE4      MOV	R30,R20
    0044 27FF      CLR	R31
    0045 0FE8      ADD	R30,R24
    0046 1FF9      ADC	R31,R25
    0047 8020      LDD	R2,Z+0
    0048 B82F      OUT	0x0F,R2
(0020) while (!(SPSR&(1<<SPIF)))
    0049 9B77      SBIS	0x0E,7
    004A CFFE      RJMP	0x0049
(0021) ;
(0022) InBuf[n]=SPDR;
    004B E680      LDI	R24,0x60
    004C E090      LDI	R25,0
    004D 2FE4      MOV	R30,R20
    004E 27FF      CLR	R31
    004F 0FE8      ADD	R30,R24
    0050 1FF9      ADC	R31,R25
    0051 B02F      IN	R2,0x0F
    0052 8220      STD	Z+0,R2
    0053 9543      INC	R20
    0054 1740      CP	R20,R16
    0055 F358      BCS	0x0041
    0056 D2ED      RCALL	pop_gset1
    0057 9508      RET
(0023) }
(0024) }
(0025) void InitPro02()//编程前的准备工作
(0026) {
(0027) DDRB=0xff;
_InitPro02:
    0058 EF8F      LDI	R24,0xFF
    0059 BB87      OUT	0x17,R24
(0028) PORTB&=~BIT(PB2);
    005A 98C2      CBI	0x18,2
(0029) Delay_ms(10);
    005B E00A      LDI	R16,0xA
    005C E010      LDI	R17,0
    005D D100      RCALL	_Delay_ms
(0030) PORTB|=BIT(PB2);
    005E 9AC2      SBI	0x18,2
(0031) PORTC|=BIT(PB1);
    005F 9AA9      SBI	0x15,1
(0032) PORTC&=~BIT(PB0);
    0060 98A8      CBI	0x15,0
(0033) Delay_ms(10);
    0061 E00A      LDI	R16,0xA
    0062 E010      LDI	R17,0
    0063 D0FA      RCALL	_Delay_ms
(0034) nAddress=0x0000;
    0064 2422      CLR	R2
    0065 2433      CLR	R3
    0066 9230008B  STS	nAddress+1,R3
    0068 9220008A  STS	nAddress,R2
(0035) OutBuf[0]=0xac;//正好在这里可以安排DataSheet上所规定的
    006A EA8C      LDI	R24,0xAC
    006B 93800064  STS	OutBuf,R24
(0036) OutBuf[1]=0x53;//Eanable Programming命令
    006D E583      LDI	R24,0x53
    006E 93800065  STS	OutBuf+1,R24
(0037) OutBuf[2]=0;
    0070 92200066  STS	OutBuf+2,R2
(0038) OutBuf[3]=0;
    0072 92200067  STS	OutBuf+3,R2
(0039) SendInstrc(4);
    0074 E004      LDI	R16,4
    0075 DFC4      RCALL	_SendInstrc
    0076 9508      RET
(0040) }
(0041) 
(0042) void ProOver02()//编程结束后的工作,设置合适的引脚电平
(0043) {
(0044) PORTC|=BIT(PB0);
_ProOver02:
    0077 9AA8      SBI	0x15,0
(0045) PORTC&=~BIT(PB1);
    0078 98A9      CBI	0x15,1
(0046) DDRB=0x00;
    0079 2422      CLR	R2
    007A BA27      OUT	0x17,R2
    007B 9508      RET
(0047) }
(0048) uchar ComBuf[18];
(0049) uchar Read02()
(0050) {
(0051) OutBuf[0]=0x20;
_Read02:
    007C E280      LDI	R24,0x20
    007D 93800064  STS	OutBuf,R24
(0052) OutBuf[1]=((uchar*)&nAddress)[1];
    007F 9020008B  LDS	R2,nAddress+1
    0081 92200065  STS	OutBuf+1,R2
(0053) OutBuf[2]=((uchar*)&nAddress)[0];
    0083 E8EA      LDI	R30,0x8A
    0084 E0F0      LDI	R31,0
    0085 8020      LDD	R2,Z+0
    0086 92200066  STS	OutBuf+2,R2
(0054) SendInstrc(4);
    0088 E004      LDI	R16,4
    0089 DFB0      RCALL	_SendInstrc
(0055) return InBuf[3];
    008A 91000063  LDS	R16,InBuf+3
    008C 9508      RET
(0056) }
(0057) 
(0058) void ReadSign02()//读特征字
(0059) {
(0060) 	InitPro02();//先设置成编程状态
_ReadSign02:
    008D DFCA      RCALL	_InitPro02
(0061) //-----------------------------------------------------------------------------
(0062) 	//根据器件的DataSheet,设置相应的编程控制信号
(0063) 	OutBuf[0]=0x28;
    008E E288      LDI	R24,0x28
    008F 93800064  STS	OutBuf,R24
(0064) 	OutBuf[1]=0x00;
    0091 2422      CLR	R2
    0092 92200065  STS	OutBuf+1,R2
(0065) 	OutBuf[2]=0x00;
    0094 92200066  STS	OutBuf+2,R2
(0066) 	OutBuf[3]=0x00;
    0096 92200067  STS	OutBuf+3,R2
(0067) 	SendInstrc(4);
    0098 E004      LDI	R16,4
    0099 DFA0      RCALL	_SendInstrc
(0068) 	ComBuf[2]=InBuf[3];
    009A 90200063  LDS	R2,InBuf+3
    009C 9220006A  STS	ComBuf+2,R2
(0069) 	OutBuf[1]=0x01;
    009E E081      LDI	R24,1
    009F 93800065  STS	OutBuf+1,R24
(0070) 	SendInstrc(4);
    00A1 E004      LDI	R16,4
    00A2 DF97      RCALL	_SendInstrc
(0071) 	ComBuf[3]=InBuf[3];
    00A3 90200063  LDS	R2,InBuf+3
    00A5 9220006B  STS	ComBuf+3,R2
(0072) 	OutBuf[1]=0x02;
    00A7 E082      LDI	R24,2
    00A8 93800065  STS	OutBuf+1,R24
(0073) 	SendInstrc(4);
    00AA E004      LDI	R16,4
    00AB DF8E      RCALL	_SendInstrc
(0074) 	ComBuf[4]=InBuf[3];
    00AC 90200063  LDS	R2,InBuf+3
    00AE 9220006C  STS	0x6C,R2
(0075) //-----------------------------------------------------------------------------
(0076) 	ProOver02();
    00B0 DFC6      RCALL	_ProOver02
    00B1 9508      RET
(0077) }
(0078) 
(0079) void Erase02()//擦除器件
(0080) {
(0081) 	InitPro02();
_Erase02:
    00B2 DFA5      RCALL	_InitPro02
(0082) //-----------------------------------------------------------------------------
(0083) 	//根据器件的DataSheet,设置相应的编程控制信号
(0084) 	OutBuf[0]=0xac;
    00B3 EA8C      LDI	R24,0xAC
    00B4 93800064  STS	OutBuf,R24
(0085) 	OutBuf[1]=0x80;
    00B6 E880      LDI	R24,0x80
    00B7 93800065  STS	OutBuf+1,R24
(0086) 	SendInstrc(4);
    00B9 E004      LDI	R16,4
    00BA DF7F      RCALL	_SendInstrc
(0087) 	Delay_ms(50);	
    00BB E302      LDI	R16,0x32
    00BC E010      LDI	R17,0
    00BD D0A0      RCALL	_Delay_ms
(0088) //-----------------------------------------------------------------------------
(0089) 	ProOver02();
    00BE DFB8      RCALL	_ProOver02
    00BF 9508      RET
_Write02:
  Data                 --> R20
    00C0 D280      RCALL	push_gset1
    00C1 2F40      MOV	R20,R16
(0090) }
(0091) 
(0092) BOOL Write02(BYTE Data)//写器件
(0093) {
(0094) 
(0095) //-----------------------------------------------------------------------------
(0096) 	//根据器件的DataSheet,设置相应的编程控制信号
(0097) 	//写一个单元
(0098) 	OutBuf[0]=0x40;
    00C2 E480      LDI	R24,0x40
    00C3 93800064  STS	OutBuf,R24
(0099) 	OutBuf[1]=((BYTE*)&nAddress)[1];
    00C5 9020008B  LDS	R2,nAddress+1
    00C7 92200065  STS	OutBuf+1,R2
(0100) 	OutBuf[2]=((BYTE*)&nAddress)[0];
    00C9 E8EA      LDI	R30,0x8A
    00CA E0F0      LDI	R31,0
    00CB 8020      LDD	R2,Z+0
    00CC 92200066  STS	OutBuf+2,R2
(0101) 	OutBuf[3]=Data;
    00CE 93400067  STS	OutBuf+3,R20
(0102) 	SendInstrc(4);
    00D0 E004      LDI	R16,4
    00D1 DF68      RCALL	_SendInstrc
(0103) 	nTimeOut=0;
    00D2 2422      CLR	R2
    00D3 2433      CLR	R3
    00D4 92300089  STS	nTimeOut+1,R3
    00D6 92200088  STS	nTimeOut,R2
    00D8 C014      RJMP	0x00ED
(0104) 	while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同
(0105) 	{
(0106) 		nTimeOut++;
    00D9 91800088  LDS	R24,nTimeOut
    00DB 91900089  LDS	R25,nTimeOut+1
    00DD 9601      ADIW	R24,1
    00DE 93900089  STS	nTimeOut+1,R25
    00E0 93800088  STS	nTimeOut,R24
(0107) 		if(nTimeOut>1000)//超时了
    00E2 EE88      LDI	R24,0xE8
    00E3 E093      LDI	R25,3
    00E4 90200088  LDS	R2,nTimeOut
    00E6 90300089  LDS	R3,nTimeOut+1
    00E8 1582      CP	R24,R2
    00E9 0593      CPC	R25,R3
    00EA F410      BCC	0x00ED
(0108) 		{
(0109) 			return  0;
    00EB 2700      CLR	R16
    00EC C004      RJMP	0x00F1
    00ED DF8E      RCALL	_Read02
    00EE 1704      CP	R16,R20
    00EF F749      BNE	0x00D9
(0110) 		}
(0111) 				
(0112) 	}
(0113) //-----------------------------------------------------------------------------
(0114) 	return 1;
    00F0 E001      LDI	R16,1
    00F1 D252      RCALL	pop_gset1
    00F2 9508      RET
(0115) }
(0116) void Lock02()//写锁定位
(0117) {
(0118) //-----------------------------------------------------------------------------
(0119) 	//根据器件的DataSheet,设置相应的编程控制信号
(0120) 	if(ComBuf[2]>=1)//ComBuf[2]为锁定位
_Lock02:
    00F3 9180006A  LDS	R24,ComBuf+2
    00F5 3081      CPI	R24,1
    00F6 F060      BCS	0x0103
(0121) 	{
(0122) 		InitPro02();
    00F7 DF60      RCALL	_InitPro02
(0123) 		OutBuf[0]=0xac;
    00F8 EA8C      LDI	R24,0xAC
    00F9 93800064  STS	OutBuf,R24
(0124) 		OutBuf[1]=0xe1;
    00FB EE81      LDI	R24,0xE1
    00FC 93800065  STS	OutBuf+1,R24
(0125) 		SendInstrc(4);
    00FE E004      LDI	R16,4
    00FF DF3A      RCALL	_SendInstrc
(0126) 		Delay_ms(1);
    0100 E001      LDI	R16,1
    0101 E010      LDI	R17,0
    0102 D05B      RCALL	_Delay_ms
(0127) 	}
(0128) 	if(ComBuf[2]>=2)
    0103 9180006A  LDS	R24,ComBuf+2
    0105 3082      CPI	R24,2
    0106 F060      BCS	0x0113
(0129) 	{
(0130) 		InitPro02();
    0107 DF50      RCALL	_InitPro02
(0131) 		OutBuf[0]=0xac;
    0108 EA8C      LDI	R24,0xAC
    0109 93800064  STS	OutBuf,R24
(0132) 		OutBuf[1]=0xe2;
    010B EE82      LDI	R24,0xE2
    010C 93800065  STS	OutBuf+1,R24
(0133) 		SendInstrc(4);
    010E E004      LDI	R16,4
    010F DF2A      RCALL	_SendInstrc
(0134) 		Delay_ms(1);
    0110 E001      LDI	R16,1
    0111 E010      LDI	R17,0
    0112 D04B      RCALL	_Delay_ms
(0135) 	}
(0136) 	if(ComBuf[2]==3)
    0113 9180006A  LDS	R24,ComBuf+2
    0115 3083      CPI	R24,3
    0116 F461      BNE	0x0123
(0137) 	{
(0138) 		InitPro02();
    0117 DF40      RCALL	_InitPro02
(0139) 		OutBuf[0]=0xac;
    0118 EA8C      LDI	R24,0xAC
    0119 93800064  STS	OutBuf,R24
(0140) 		OutBuf[1]=0xe3;
    011B EE83      LDI	R24,0xE3
    011C 93800065  STS	OutBuf+1,R24
(0141) 		SendInstrc(4);
    011E E004      LDI	R16,4
    011F DF1A      RCALL	_SendInstrc
(0142) 		Delay_ms(1);
    0120 E001      LDI	R16,1
    0121 E010      LDI	R17,0
    0122 D03B      RCALL	_Delay_ms
(0143) 	}
(0144) //-----------------------------------------------------------------------------
(0145) 	ProOver02();
    0123 DF53      RCALL	_ProOver02
    0124 9508      RET
(0146) }
(0147) void PreparePro02()//设置pw中的函数指针,让主程序可以调用上面的函数
(0148) {
(0149) 	pw.fpInitPro=InitPro02;
_PreparePro02:
    0125 E382      LDI	R24,0x32
    0126 E090      LDI	R25,0
    0127 9390007B  STS	pw+1,R25
    0129 9380007A  STS	pw,R24
(0150) 	pw.fpReadSign=ReadSign02;
    012B E380      LDI	R24,0x30
    012C E090      LDI	R25,0
    012D 9390007D  STS	pw+3,R25
    012F 9380007C  STS	pw+2,R24
(0151) 	pw.fpErase=Erase02;
    0131 E28E      LDI	R24,0x2E
    0132 E090      LDI	R25,0
    0133 9390007F  STS	0x7F,R25

⌨️ 快捷键说明

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