📄 51.lst
字号:
__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 + -