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

📄 at24c01.s

📁 通过MEGA128的串口对I2C芯片24c01的读写程序
💻 S
字号:
	.module AT24C01.c
	.area text(rom, con, rel)
	.dbfile D:\avrvi\AVRVi_m128_Starter_Kit\USART_24C01\source\lib\AT24C01.c
	.dbfunc e wt24c_fc _wt24c_fc fpc
;              t -> R12
;              n -> R22
;             ad -> R10,R11
;              p -> R20,R21
	.even
_wt24c_fc::
	xcall push_gset4
	movw R10,R18
	movw R20,R16
	ldd R22,y+8
	.dbline -1
	.dbline 22
; /************************************************
; 文件:AT24C01.c
; 用途:AT24C01操作函数
; 注意:
; 创建:2008.1.26
; 修改:2008.1.26
; Copy Right  (c)  www.avrvi.com  AVR与虚拟仪器
; ************************************************/
; #include "..\config.h"
; unsigned char syserr;
; /*************************************************************************
; ** 函数名称: unsigned char * wt24c_fc(unsigned char *p, unsigned int ad, unsigned char n)
; ** 功能描述: 向24Cxx写入数据wt24c_h()所要调用的函数
; ** 输 入: 
; ** 输出	 : 返回写入n个字节后的主机内存指针
; ** 全局变量: 无
; ** 调用模块: 
; ** 说明:
; ** 注意:
; **************************************************************************/
; unsigned char * wt24c_fc(unsigned char *p, unsigned int ad, unsigned char n)
; {
	.dbline 23
; 	unsigned char t=0;
	clr R12
	.dbline 26
; 
; 	#if e2prom<32
; 	t=ad>>8;
	movw R12,R10
	mov R12,R13
	clr R13
	.dbline 27
; 	t<<=1;
	lsl R12
	.dbline 30
; 	#endif
; 	
; 	i2cstart();					//发送起始信号
	xcall _i2cstart
	.dbline 32
; 		
; 	if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址
	mov R16,R12
	subi R16,96    ; addi 160
	xcall _i2cwt
	cpi R16,24
	brne L3
	.dbline 33
; 	{	
	.dbline 37
; 		#if e2prom>16
; 		i2cwt(ad>>8);			//ad_dst的高位到器件
; 		#endif
; 		i2cwt(ad);				//ad_dst的低位到器件
	mov R16,R10
	xcall _i2cwt
	.dbline 39
; 			
; 		for(;n>0;n--)			//发送要写入的数据
	xjmp L8
L5:
	.dbline 40
	.dbline 41
	movw R30,R20
	ldd R16,z+0
	xcall _i2cwt
	.dbline 42
	subi R20,255  ; offset = 1
	sbci R21,255
	.dbline 43
L6:
	.dbline 39
	dec R22
L8:
	.dbline 39
	clr R2
	cp R2,R22
	brlo L5
	.dbline 44
; 		{
; 		    i2cwt(*p);
; 			p++;
; 		}
; 	}
	xjmp L4
L3:
	.dbline 45
; 	else syserr=ERR_SLAW;		//写字节命令及器件地址错
	ldi R24,1
	sts _syserr,R24
L4:
	.dbline 47
; 	
; 	i2cstop();
	xcall _i2cstop
	.dbline 48
;     delay_nms(6);						//延时6ms
	ldi R16,6
	ldi R17,0
	xcall _delay_nms
	.dbline 50
; 	
; 	return(p);
	movw R16,R20
	.dbline -2
L2:
	xcall pop_gset4
	.dbline 0 ; func end
	ret
	.dbsym r t 12 c
	.dbsym r n 22 c
	.dbsym r ad 10 i
	.dbsym r p 20 pc
	.dbend
	.dbfunc e wt24c _wt24c fV
;              n -> R10,R11
;            num -> R12,R13
;         ad_dst -> R14,R15
;          p_rsc -> y+11
	.even
_wt24c::
	xcall push_arg4
	xcall push_gset5
	movw R14,R18
	sbiw R28,1
	ldd R12,y+15
	ldd R13,y+16
	.dbline -1
	.dbline 63
; }
; /*************************************************************************
; ** 函数名称: 
; ** 功能描述: 向24Cxx写入数据
; ** 输 入: *p_rsc要输出数据的主机内存地址指针; ad_dst要写入数据的i2c的地址(双字节); num数据个数
; ** 输出	 : 
; ** 全局变量: 无
; ** 调用模块: 
; ** 说明:ad_dst: ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
; ** 注意:
; **************************************************************************/
; void wt24c(unsigned char *p_rsc, unsigned int ad_dst, unsigned int num)
; {
	.dbline 66
;     unsigned int n;
; 
;     n=ad_dst/PAGE_SIZE;		//确定地址与块地址的差
	movw R10,R14
	lsr R11
	ror R10
	lsr R11
	ror R10
	lsr R11
	ror R10
	.dbline 67
; 	if(n) n=(unsigned long)PAGE_SIZE*(n+1)-ad_dst;
	tst R10
	brne X0
	tst R11
	breq L10
X0:
	.dbline 67
	movw R24,R10
	adiw R24,1
	movw R2,R24
	clr R4
	clr R5
	ldi R20,8
	ldi R21,0
	ldi R22,0
	ldi R23,0
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	movw R16,R20
	movw R18,R22
	xcall empy32u
	movw R2,R16
	movw R4,R18
	movw R6,R14
	clr R8
	clr R9
	sub R2,R6
	sbc R3,R7
	sbc R4,R8
	sbc R5,R9
	movw R10,R2
	xjmp L11
L10:
	.dbline 68
; 	else n=PAGE_SIZE-ad_dst;
	ldi R24,8
	ldi R25,0
	movw R10,R24
	sub R10,R14
	sbc R11,R15
L11:
	.dbline 70
; 	
;     if(n>=num)		//如果ad_dst所在的数据块的末尾地址 >= ad_dst + num, 就直接写入num个数据
	cp R10,R12
	cpc R11,R13
	brlo L12
	.dbline 71
;     {
	.dbline 72
; 	 	wt24c_fc(p_rsc, ad_dst, num);
	std y+0,R12
	movw R18,R14
	ldd R16,y+11
	ldd R17,y+12
	xcall _wt24c_fc
	.dbline 73
;     	if(syserr!=0) return;
	lds R2,_syserr
	tst R2
	brne X3
	xjmp L13
X3:
	.dbline 73
	xjmp L9
X1:
	.dbline 74
;     }
L12:
	.dbline 76
;     else			//如果ad_dst所在的数据块末尾地址 < ad_dst + num, 就先写入ad_dst所在的数据块末尾地址与 ad_dst 之差个数据
;     {
	.dbline 77
; 	    p_rsc=wt24c_fc(p_rsc, ad_dst, n);
	std y+0,R10
	movw R18,R14
	ldd R16,y+11
	ldd R17,y+12
	xcall _wt24c_fc
	std y+12,R17
	std y+11,R16
	.dbline 78
;     	if(syserr!=0) return;
	lds R2,_syserr
	tst R2
	breq L16
	.dbline 78
	xjmp L9
L16:
	.dbline 80
; 		
; 		num-=n;     //更新剩下数据个数
	sub R12,R10
	sbc R13,R11
	.dbline 81
;         ad_dst+=n;	//更新剩下数据的起始地址
	add R14,R10
	adc R15,R11
	xjmp L19
L18:
	.dbline 85
; 
;         //把剩下数据写入器件
;         while(num>=PAGE_SIZE)	//先按PAGE_SIZE为长度一页一页的写入
;         {
	.dbline 86
; 		 	p_rsc=wt24c_fc(p_rsc, ad_dst, PAGE_SIZE);
	ldi R24,8
	std y+0,R24
	movw R18,R14
	ldd R16,y+11
	ldd R17,y+12
	xcall _wt24c_fc
	std y+12,R17
	std y+11,R16
	.dbline 87
;         	if(syserr!=0) return;
	lds R2,_syserr
	tst R2
	breq L21
	.dbline 87
	xjmp L9
L21:
	.dbline 89
	movw R24,R12
	sbiw R24,8
	movw R12,R24
	.dbline 90
	movw R24,R14
	adiw R24,8
	movw R14,R24
	.dbline 91
L19:
	.dbline 84
	movw R24,R12
	cpi R24,8
	ldi R30,0
	cpc R25,R30
	brsh L18
	.dbline 93
;         	
;             num-=PAGE_SIZE;		//更新剩余数据个数
;         	ad_dst+=PAGE_SIZE;	//更新剩下数据的起始地址
; 		}
;         
; 		if(num)			//把最后剩下的小于一个PAGE_SIZE长度的数据写入器件
	cpi R24,0
	cpc R24,R25
	breq L23
X2:
	.dbline 94
; 			wt24c_fc(p_rsc, ad_dst, num);
	std y+0,R12
	movw R18,R14
	ldd R16,y+11
	ldd R17,y+12
	xcall _wt24c_fc
L23:
	.dbline 95
L13:
	.dbline -2
L9:
	adiw R28,1
	xcall pop_gset5
	adiw R28,4
	.dbline 0 ; func end
	ret
	.dbsym r n 10 i
	.dbsym r num 12 i
	.dbsym r ad_dst 14 i
	.dbsym l p_rsc 11 pc
	.dbend
	.dbfunc e rd24c _rd24c fV
;              t -> R10
;            num -> R22,R23
;         ad_rsc -> R12,R13
;          p_dst -> R20,R21
	.even
_rd24c::
	xcall push_gset4
	movw R12,R18
	movw R20,R16
	ldd R22,y+8
	ldd R23,y+9
	.dbline -1
	.dbline 108
;     }
; }
; /*************************************************************************
; ** 函数名称: 
; ** 功能描述: 从24cxx读出数据
; ** 输 入: *p_dst要读入数据的主机内存地址指针; ad_rsc要输出数据的i2c的地址(整形); num数据个数(整形)
; ** 输出	 : 
; ** 全局变量: 无
; ** 调用模块: 
; ** 说明:ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
; ** 注意:
; **************************************************************************/
; void rd24c(unsigned char *p_dst, unsigned int ad_rsc, unsigned int num)
; {
	.dbline 109
;     unsigned char t=0;
	clr R10
	.dbline 112
; 
; 	#if e2prom<32
; 	t=ad_rsc>>8;
	movw R10,R12
	mov R10,R11
	clr R11
	.dbline 113
; 	t<<=1;
	lsl R10
	.dbline 116
; 	#endif
; 	
; 	i2cstart();					//发送起始信号
	xcall _i2cstart
	.dbline 118
; 		
; 	if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址
	mov R16,R10
	subi R16,96    ; addi 160
	xcall _i2cwt
	cpi R16,24
	brne L26
	.dbline 119
; 	{	
	.dbline 123
; 		#if e2prom>16
; 		i2cwt(ad_rsc>>8);		//ad_rsc的高位,  发送要读出数据的地址
; 		#endif
; 		i2cwt(ad_rsc);			//ad_rsc的低位
	mov R16,R12
	xcall _i2cwt
	.dbline 125
; 				
; 		i2cstart();				//再发送起始信号
	xcall _i2cstart
	.dbline 126
; 		i2cwt(R_ADD_COM+t);		//发送SLA_R, 读命令字节及器件地址
	mov R16,R10
	subi R16,95    ; addi 161
	xcall _i2cwt
	.dbline 128
; 				
; 		for(;num>0;num--)
	xjmp L31
L28:
	.dbline 129
	.dbline 130
	xcall _i2crd
	movw R30,R20
	std z+0,R16
	.dbline 131
	subi R20,255  ; offset = 1
	sbci R21,255
	.dbline 132
L29:
	.dbline 128
	subi R22,1
	sbci R23,0
L31:
	.dbline 128
	cpi R22,0
	cpc R22,R23
	brne L28
X4:
	.dbline 133
; 		{
; 		    *p_dst=i2crd();		//从器件读出一个字节
; 			p_dst++;
; 		}
; 	}
	xjmp L27
L26:
	.dbline 134
; 	else syserr=ERR_SLAW;		//写字节命令及器件地址错或对方无应答
	ldi R24,1
	sts _syserr,R24
L27:
	.dbline 136
; 		
; 	i2cstop();
	xcall _i2cstop
	.dbline -2
L25:
	xcall pop_gset4
	.dbline 0 ; func end
	ret
	.dbsym r t 10 c
	.dbsym r num 22 i
	.dbsym r ad_rsc 12 i
	.dbsym r p_dst 20 pc
	.dbend
	.area bss(ram, con, rel)
	.dbfile D:\avrvi\AVRVi_m128_Starter_Kit\USART_24C01\source\lib\AT24C01.c
_syserr::
	.blkb 1
	.dbsym e syserr _syserr c

⌨️ 快捷键说明

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