📄 at24c01.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 + -