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

📄 s51.s

📁 笔者的《用M8L制作的89S51单片机 USB下载线》在无线电2007年第9期已刊登过
💻 S
字号:
	.module s51.c
	.area text(rom, con, rel)
	.dbfile E:\学习专区\AVR专区\个人创作区\ICC\s51.c
	.dbfunc e SendInstrc _SendInstrc fV
;              n -> R20
;          nByte -> R16
	.even
_SendInstrc::
	rcall push_gset1
	.dbline -1
	.dbline 13
; ///////////////////////////////////////////////////////////////////////////////////////////////////
; //FID=02:AT89S51系列编程器 
; //实现编程的读,写,擦等细节
; ///////////////////////////////////////////////////////////////////////////////////////////////////
; #include <iom8v.h>
; #include <macros.h>
; #include<signal.h>
; #include<e51pro.h>
; #define uchar unsigned char 
; BYTE OutBuf[4];//发送命令缓冲
; BYTE InBuf[4];//接收缓冲
; void SendInstrc(uchar nByte)//用MOSI串行发送命令的同时用MISO接收相关数据
; {
	.dbline 14
; uchar n=0;
	clr R20
	.dbline 15
; DDRB=(1<<PB5)|(1<<PB3)|(1<<PB2);
	ldi R24,44
	out 0x17,R24
	.dbline 16
; SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);//SCK时钟为fosc/16
	ldi R24,81
	out 0xd,R24
	.dbline 17
; for (n=0;n<nByte;n++)
	rjmp L5
L2:
	.dbline 18
; {
	.dbline 19
; SPDR=OutBuf[n];
	ldi R24,<_OutBuf
	ldi R25,>_OutBuf
	mov R30,R20
	clr R31
	add R30,R24
	adc R31,R25
	ldd R2,z+0
	out 0xf,R2
L6:
	.dbline 21
L7:
	.dbline 20
	sbis 0xe,7
	rjmp L6
	.dbline 22
	ldi R24,<_InBuf
	ldi R25,>_InBuf
	mov R30,R20
	clr R31
	add R30,R24
	adc R31,R25
	in R2,0xf
	std z+0,R2
	.dbline 23
L3:
	.dbline 17
	inc R20
L5:
	.dbline 17
	cp R20,R16
	brlo L2
	.dbline -2
L1:
	rcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r n 20 c
	.dbsym r nByte 16 c
	.dbend
	.dbfunc e InitPro02 _InitPro02 fV
	.even
_InitPro02::
	.dbline -1
	.dbline 26
; while (!(SPSR&(1<<SPIF)))
; ;
; InBuf[n]=SPDR;
; }
; }
; void InitPro02()//编程前的准备工作
; {
	.dbline 27
; DDRB=0xff;
	ldi R24,255
	out 0x17,R24
	.dbline 28
; PORTB&=~BIT(PB2);
	cbi 0x18,2
	.dbline 29
; Delay_ms(10);
	ldi R16,10
	ldi R17,0
	rcall _Delay_ms
	.dbline 30
; PORTB|=BIT(PB2);
	sbi 0x18,2
	.dbline 31
; PORTC|=BIT(PB1);
	sbi 0x15,1
	.dbline 32
; PORTC&=~BIT(PB0);
	cbi 0x15,0
	.dbline 33
; Delay_ms(10);
	ldi R16,10
	ldi R17,0
	rcall _Delay_ms
	.dbline 34
; nAddress=0x0000;
	clr R2
	clr R3
	sts _nAddress+1,R3
	sts _nAddress,R2
	.dbline 35
; OutBuf[0]=0xac;//正好在这里可以安排DataSheet上所规定的
	ldi R24,172
	sts _OutBuf,R24
	.dbline 36
; OutBuf[1]=0x53;//Eanable Programming命令
	ldi R24,83
	sts _OutBuf+1,R24
	.dbline 37
; OutBuf[2]=0;
	sts _OutBuf+2,R2
	.dbline 38
; OutBuf[3]=0;
	sts _OutBuf+3,R2
	.dbline 39
; SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline -2
L9:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e ProOver02 _ProOver02 fV
	.even
_ProOver02::
	.dbline -1
	.dbline 43
; }
; 
; void ProOver02()//编程结束后的工作,设置合适的引脚电平
; {
	.dbline 44
; PORTC|=BIT(PB0);
	sbi 0x15,0
	.dbline 45
; PORTC&=~BIT(PB1);
	cbi 0x15,1
	.dbline 46
; DDRB=0x00;
	clr R2
	out 0x17,R2
	.dbline -2
L13:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e Read02 _Read02 fc
	.even
_Read02::
	.dbline -1
	.dbline 50
; }
; uchar ComBuf[18];
; uchar Read02()
; {
	.dbline 51
; OutBuf[0]=0x20;
	ldi R24,32
	sts _OutBuf,R24
	.dbline 52
; OutBuf[1]=((uchar*)&nAddress)[1];
	lds R2,_nAddress+1
	sts _OutBuf+1,R2
	.dbline 53
; OutBuf[2]=((uchar*)&nAddress)[0];
	ldi R30,<_nAddress
	ldi R31,>_nAddress
	ldd R2,z+0
	sts _OutBuf+2,R2
	.dbline 54
; SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 55
; return InBuf[3];
	lds R16,_InBuf+3
	.dbline -2
L14:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e ReadSign02 _ReadSign02 fV
	.even
_ReadSign02::
	.dbline -1
	.dbline 59
; }
; 
; void ReadSign02()//读特征字
; {
	.dbline 60
; 	InitPro02();//先设置成编程状态
	rcall _InitPro02
	.dbline 63
; //-----------------------------------------------------------------------------
; 	//根据器件的DataSheet,设置相应的编程控制信号
; 	OutBuf[0]=0x28;
	ldi R24,40
	sts _OutBuf,R24
	.dbline 64
; 	OutBuf[1]=0x00;
	clr R2
	sts _OutBuf+1,R2
	.dbline 65
; 	OutBuf[2]=0x00;
	sts _OutBuf+2,R2
	.dbline 66
; 	OutBuf[3]=0x00;
	sts _OutBuf+3,R2
	.dbline 67
; 	SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 68
; 	ComBuf[2]=InBuf[3];
	lds R2,_InBuf+3
	sts _ComBuf+2,R2
	.dbline 69
; 	OutBuf[1]=0x01;
	ldi R24,1
	sts _OutBuf+1,R24
	.dbline 70
; 	SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 71
; 	ComBuf[3]=InBuf[3];
	lds R2,_InBuf+3
	sts _ComBuf+3,R2
	.dbline 72
; 	OutBuf[1]=0x02;
	ldi R24,2
	sts _OutBuf+1,R24
	.dbline 73
; 	SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 74
; 	ComBuf[4]=InBuf[3];
	lds R2,_InBuf+3
	sts _ComBuf+4,R2
	.dbline 76
; //-----------------------------------------------------------------------------
; 	ProOver02();
	rcall _ProOver02
	.dbline -2
L19:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e Erase02 _Erase02 fV
	.even
_Erase02::
	.dbline -1
	.dbline 80
; }
; 
; void Erase02()//擦除器件
; {
	.dbline 81
; 	InitPro02();
	rcall _InitPro02
	.dbline 84
; //-----------------------------------------------------------------------------
; 	//根据器件的DataSheet,设置相应的编程控制信号
; 	OutBuf[0]=0xac;
	ldi R24,172
	sts _OutBuf,R24
	.dbline 85
; 	OutBuf[1]=0x80;
	ldi R24,128
	sts _OutBuf+1,R24
	.dbline 86
; 	SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 87
; 	Delay_ms(50);	
	ldi R16,50
	ldi R17,0
	rcall _Delay_ms
	.dbline 89
; //-----------------------------------------------------------------------------
; 	ProOver02();
	rcall _ProOver02
	.dbline -2
L31:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e Write02 _Write02 fc
;           Data -> R20
	.even
_Write02::
	rcall push_gset1
	mov R20,R16
	.dbline -1
	.dbline 93
; }
; 
; BOOL Write02(BYTE Data)//写器件
; {
	.dbline 98
; 
; //-----------------------------------------------------------------------------
; 	//根据器件的DataSheet,设置相应的编程控制信号
; 	//写一个单元
; 	OutBuf[0]=0x40;
	ldi R24,64
	sts _OutBuf,R24
	.dbline 99
; 	OutBuf[1]=((BYTE*)&nAddress)[1];
	lds R2,_nAddress+1
	sts _OutBuf+1,R2
	.dbline 100
; 	OutBuf[2]=((BYTE*)&nAddress)[0];
	ldi R30,<_nAddress
	ldi R31,>_nAddress
	ldd R2,z+0
	sts _OutBuf+2,R2
	.dbline 101
; 	OutBuf[3]=Data;
	sts _OutBuf+3,R20
	.dbline 102
; 	SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 103
; 	nTimeOut=0;
	clr R2
	clr R3
	sts _nTimeOut+1,R3
	sts _nTimeOut,R2
	rjmp L39
L38:
	.dbline 105
; 	while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同
; 	{
	.dbline 106
; 		nTimeOut++;
	lds R24,_nTimeOut
	lds R25,_nTimeOut+1
	adiw R24,1
	sts _nTimeOut+1,R25
	sts _nTimeOut,R24
	.dbline 107
; 		if(nTimeOut>1000)//超时了
	ldi R24,1000
	ldi R25,3
	lds R2,_nTimeOut
	lds R3,_nTimeOut+1
	cp R24,R2
	cpc R25,R3
	brsh L41
	.dbline 108
; 		{
	.dbline 109
; 			return  0;
	clr R16
	rjmp L33
L41:
	.dbline 112
L39:
	.dbline 104
	rcall _Read02
	cp R16,R20
	brne L38
	.dbline 114
; 		}
; 				
; 	}
; //-----------------------------------------------------------------------------
; 	return 1;
	ldi R16,1
	.dbline -2
L33:
	rcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r Data 20 c
	.dbend
	.dbfunc e Lock02 _Lock02 fV
	.even
_Lock02::
	.dbline -1
	.dbline 117
; }
; void Lock02()//写锁定位
; {
	.dbline 120
; //-----------------------------------------------------------------------------
; 	//根据器件的DataSheet,设置相应的编程控制信号
; 	if(ComBuf[2]>=1)//ComBuf[2]为锁定位
	lds R24,_ComBuf+2
	cpi R24,1
	brlo L44
	.dbline 121
; 	{
	.dbline 122
; 		InitPro02();
	rcall _InitPro02
	.dbline 123
; 		OutBuf[0]=0xac;
	ldi R24,172
	sts _OutBuf,R24
	.dbline 124
; 		OutBuf[1]=0xe1;
	ldi R24,225
	sts _OutBuf+1,R24
	.dbline 125
; 		SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 126
; 		Delay_ms(1);
	ldi R16,1
	ldi R17,0
	rcall _Delay_ms
	.dbline 127
; 	}
L44:
	.dbline 128
; 	if(ComBuf[2]>=2)
	lds R24,_ComBuf+2
	cpi R24,2
	brlo L48
	.dbline 129
; 	{
	.dbline 130
; 		InitPro02();
	rcall _InitPro02
	.dbline 131
; 		OutBuf[0]=0xac;
	ldi R24,172
	sts _OutBuf,R24
	.dbline 132
; 		OutBuf[1]=0xe2;
	ldi R24,226
	sts _OutBuf+1,R24
	.dbline 133
; 		SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 134
; 		Delay_ms(1);
	ldi R16,1
	ldi R17,0
	rcall _Delay_ms
	.dbline 135
; 	}
L48:
	.dbline 136
; 	if(ComBuf[2]==3)
	lds R24,_ComBuf+2
	cpi R24,3
	brne L52
	.dbline 137
; 	{
	.dbline 138
; 		InitPro02();
	rcall _InitPro02
	.dbline 139
; 		OutBuf[0]=0xac;
	ldi R24,172
	sts _OutBuf,R24
	.dbline 140
; 		OutBuf[1]=0xe3;
	ldi R24,227
	sts _OutBuf+1,R24
	.dbline 141
; 		SendInstrc(4);
	ldi R16,4
	rcall _SendInstrc
	.dbline 142
; 		Delay_ms(1);
	ldi R16,1
	ldi R17,0
	rcall _Delay_ms
	.dbline 143
; 	}
L52:
	.dbline 145
; //-----------------------------------------------------------------------------
; 	ProOver02();
	rcall _ProOver02
	.dbline -2
L43:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e PreparePro02 _PreparePro02 fV
	.even
_PreparePro02::
	.dbline -1
	.dbline 148
; }
; void PreparePro02()//设置pw中的函数指针,让主程序可以调用上面的函数
; {
	.dbline 149
; 	pw.fpInitPro=InitPro02;
	ldi R24,<PL_InitPro02
	ldi R25,>PL_InitPro02
	sts _pw+1,R25
	sts _pw,R24
	.dbline 150
; 	pw.fpReadSign=ReadSign02;
	ldi R24,<PL_ReadSign02
	ldi R25,>PL_ReadSign02
	sts _pw+2+1,R25
	sts _pw+2,R24
	.dbline 151
; 	pw.fpErase=Erase02;
	ldi R24,<PL_Erase02
	ldi R25,>PL_Erase02
	sts _pw+4+1,R25
	sts _pw+4,R24
	.dbline 152
; 	pw.fpWrite=Write02;
	ldi R24,<PL_Write02
	ldi R25,>PL_Write02
	sts _pw+6+1,R25
	sts _pw+6,R24
	.dbline 153
; 	pw.fpRead=Read02;
	ldi R24,<PL_Read02
	ldi R25,>PL_Read02
	sts _pw+8+1,R25
	sts _pw+8,R24
	.dbline 154
; 	pw.fpLock=Lock02;
	ldi R24,<PL_Lock02
	ldi R25,>PL_Lock02
	sts _pw+10+1,R25
	sts _pw+10,R24
	.dbline 155
; 	pw.fpProOver=ProOver02;
	ldi R24,<PL_ProOver02
	ldi R25,>PL_ProOver02
	sts _pw+12+1,R25
	sts _pw+12,R24
	.dbline -2
L56:
	.dbline 0 ; func end
	ret
	.dbend
	.area bss(ram, con, rel)
	.dbfile E:\学习专区\AVR专区\个人创作区\ICC\s51.c
_InBuf::
	.blkb 4
	.dbsym e InBuf _InBuf A[4:4]c
_OutBuf::
	.blkb 4
	.dbsym e OutBuf _OutBuf A[4:4]c
_ComBuf::
	.blkb 18
	.dbsym e ComBuf _ComBuf A[18:18]c
	.area func_lit
PL_ProOver02:	.word `_ProOver02
PL_Lock02:	.word `_Lock02
PL_Read02:	.word `_Read02
PL_Write02:	.word `_Write02
PL_Erase02:	.word `_Erase02
PL_ReadSign02:	.word `_ReadSign02
PL_InitPro02:	.word `_InitPro02

⌨️ 快捷键说明

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