📄 24cxx.lis
字号:
.module _24Cxx.C
.area text(rom, con, rel)
0000 .dbfile E:\avr\m16_twi_24x\24Cxx.C
0000 .dbfunc e wt24c _wt24c fV
0000 ; n -> R10,R11
0000 ; num -> R12,R13
0000 ; ad_dst -> R14,R15
0000 ; p_rsc -> y+11
.even
0000 _wt24c::
0000 0E940000 xcall push_arg4
0004 0E940000 xcall push_gset5
0008 7901 movw R14,R18
000A 2197 sbiw R28,1
000C CF84 ldd R12,y+15
000E D888 ldd R13,y+16
0010 .dbline -1
0010 .dbline 72
0010 ; #include<iom16v.h>
0010 ; #include<macros.h>
0010 ; #include"xd.h"
0010 ; #include"xdprj.h"
0010 ;
0010 ;
0010 ;
0010 ; //------在此设定芯片型号------
0010 ; #define e2prom 1 // <---在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
0010 ;
0010 ; #if e2prom==1
0010 ; #define PAGE_SIZE 8
0010 ; #define SIZE 0x007f
0010 ; #elif e2prom==2
0010 ; #define PAGE_SIZE 8
0010 ; #define SIZE 0x00ff
0010 ; #elif e2prom==4
0010 ; #define PAGE_SIZE 16
0010 ; #define SIZE 0x01ff
0010 ; #elif e2prom==8
0010 ; #define PAGE_SIZE 16
0010 ; #define SIZE 0x03ff
0010 ; #elif e2prom==16
0010 ; #define PAGE_SIZE 16
0010 ; #define SIZE 0x07ff
0010 ; #elif e2prom==32
0010 ; #define PAGE_SIZE 32
0010 ; #define SIZE 0x0fff
0010 ; #elif e2prom==64
0010 ; #define PAGE_SIZE 32
0010 ; #define SIZE 0x1fff
0010 ; #elif e2prom==128
0010 ; #define PAGE_SIZE 64
0010 ; #define SIZE 0x3fff
0010 ; #elif e2prom==256
0010 ; #define PAGE_SIZE 64
0010 ; #define SIZE 0x7fff
0010 ; #elif e2prom==512
0010 ; #define PAGE_SIZE 128
0010 ; #define SIZE 0xffff
0010 ; #endif
0010 ; //--------------------------
0010 ;
0010 ; //--------在此设定芯片地址-------
0010 ; #define W_ADD_COM 0xa0 //写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
0010 ; #define R_ADD_COM 0xa1 //读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
0010 ; //-------------------------------
0010 ;
0010 ;
0010 ;
0010 ; #define SLAW 0x18 //SLA_W 已正常发送代码,判断器件是否正常应答的常量.
0010 ;
0010 ; //-----在此改变预置错误号-----
0010 ; #define ERR_SLAW ERR_10 //写字节命令及器件地址错, 在此也就是读写器件错!!
0010 ; //---------------------------
0010 ;
0010 ;
0010 ;
0010 ; //-----------4个I2总线公用函数, 可供其它I2总线器件的程序调用--------------
0010 ; void i2cstart(void); //总线上起动开始条件
0010 ; uchar i2cwt(uchar a); //把一个字节数据输入器件, 返回TWI状态
0010 ; uchar i2crd(void); //i2c读要调用的函数
0010 ; void i2cstop(void); //总线上起动停止条件
0010 ; //------------------------------------------------------------------------
0010 ;
0010 ; uchar * wt24c_fc(uchar *p, uint ad, uchar n); //向24Cxx写入数据wt24c_h()所要调用的函数
0010 ;
0010 ; //向24Cxx写入数据
0010 ; //参数: *p_rsc要输出数据的主机内存地址指针; ad_dst要写入数据的i2c的地址(双字节); num数据个数
0010 ; //参数条件: ad_dst: ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
0010 ; void wt24c(uchar *p_rsc, uint ad_dst, uint num)
0010 ; { uint n;
0010 .dbline 74
0010 ;
0010 ; n=ad_dst/PAGE_SIZE; //确定地址与块地址的差
0010 5701 movw R10,R14
0012 B694 lsr R11
0014 A794 ror R10
0016 B694 lsr R11
0018 A794 ror R10
001A B694 lsr R11
001C A794 ror R10
001E .dbline 75
001E ; if(n) n=(ulong)PAGE_SIZE*(n+1)-ad_dst;
001E AA20 tst R10
0020 11F4 brne X0
0022 BB20 tst R11
0024 E1F0 breq L2
0026 X0:
0026 .dbline 75
0026 C501 movw R24,R10
0028 0196 adiw R24,1
002A 1C01 movw R2,R24
002C 4424 clr R4
002E 5524 clr R5
0030 48E0 ldi R20,8
0032 50E0 ldi R21,0
0034 60E0 ldi R22,0
0036 70E0 ldi R23,0
0038 5A92 st -y,R5
003A 4A92 st -y,R4
003C 3A92 st -y,R3
003E 2A92 st -y,R2
0040 8A01 movw R16,R20
0042 9B01 movw R18,R22
0044 0E940000 xcall empy32u
0048 1801 movw R2,R16
004A 2901 movw R4,R18
004C 3701 movw R6,R14
004E 8824 clr R8
0050 9924 clr R9
0052 2618 sub R2,R6
0054 3708 sbc R3,R7
0056 4808 sbc R4,R8
0058 5908 sbc R5,R9
005A 5101 movw R10,R2
005C 05C0 xjmp L3
005E L2:
005E .dbline 76
005E ; else n=PAGE_SIZE-ad_dst;
005E 88E0 ldi R24,8
0060 90E0 ldi R25,0
0062 5C01 movw R10,R24
0064 AE18 sub R10,R14
0066 BF08 sbc R11,R15
0068 L3:
0068 .dbline 78
0068 ;
0068 ; if(n>=num) //如果ad_dst所在的数据块的末尾地址 >= ad_dst + num, 就直接写入num个数据
0068 AC14 cp R10,R12
006A BD04 cpc R11,R13
006C 58F0 brlo L4
006E .dbline 79
006E ; { wt24c_fc(p_rsc, ad_dst, num);
006E .dbline 79
006E C882 std y+0,R12
0070 9701 movw R18,R14
0072 0B85 ldd R16,y+11
0074 1C85 ldd R17,y+12
0076 66D0 xcall _wt24c_fc
0078 .dbline 80
0078 ; if(syserr!=0) return;
0078 20900000 lds R2,_syserr
007C 2220 tst R2
007E 09F4 brne X3
0080 32C0 xjmp L5
0082 X3:
0082 .dbline 80
0082 31C0 xjmp L1
0084 X1:
0084 .dbline 81
0084 ; }
0084 L4:
0084 .dbline 83
0084 ; else //如果ad_dst所在的数据块末尾地址 < ad_dst + num, 就先写入ad_dst所在的数据块末尾地址与 ad_dst 之差个数据
0084 ; { p_rsc=wt24c_fc(p_rsc, ad_dst, n);
0084 .dbline 83
0084 A882 std y+0,R10
0086 9701 movw R18,R14
0088 0B85 ldd R16,y+11
008A 1C85 ldd R17,y+12
008C 5BD0 xcall _wt24c_fc
008E 1C87 std y+12,R17
0090 0B87 std y+11,R16
0092 .dbline 84
0092 ; if(syserr!=0) return;
0092 20900000 lds R2,_syserr
0096 2220 tst R2
0098 09F0 breq L8
009A .dbline 84
009A 25C0 xjmp L1
009C L8:
009C .dbline 86
009C ;
009C ; num-=n; //更新剩下数据个数
009C CA18 sub R12,R10
009E DB08 sbc R13,R11
00A0 .dbline 87
00A0 ; ad_dst+=n; //更新剩下数据的起始地址
00A0 EA0C add R14,R10
00A2 FB1C adc R15,R11
00A4 13C0 xjmp L11
00A6 L10:
00A6 .dbline 91
00A6 ;
00A6 ; //把剩下数据写入器件
00A6 ; while(num>=PAGE_SIZE) //先按PAGE_SIZE为长度一页一页的写入
00A6 ; { p_rsc=wt24c_fc(p_rsc, ad_dst, PAGE_SIZE);
00A6 .dbline 91
00A6 88E0 ldi R24,8
00A8 8883 std y+0,R24
00AA 9701 movw R18,R14
00AC 0B85 ldd R16,y+11
00AE 1C85 ldd R17,y+12
00B0 49D0 xcall _wt24c_fc
00B2 1C87 std y+12,R17
00B4 0B87 std y+11,R16
00B6 .dbline 92
00B6 ; if(syserr!=0) return;
00B6 20900000 lds R2,_syserr
00BA 2220 tst R2
00BC 09F0 breq L13
00BE .dbline 92
00BE 13C0 xjmp L1
00C0 L13:
00C0 .dbline 94
00C0 C601 movw R24,R12
00C2 0897 sbiw R24,8
00C4 6C01 movw R12,R24
00C6 .dbline 95
00C6 C701 movw R24,R14
00C8 0896 adiw R24,8
00CA 7C01 movw R14,R24
00CC .dbline 96
00CC L11:
00CC .dbline 90
00CC C601 movw R24,R12
00CE 8830 cpi R24,8
00D0 E0E0 ldi R30,0
00D2 9E07 cpc R25,R30
00D4 40F7 brsh L10
00D6 .dbline 98
00D6 ;
00D6 ; num-=PAGE_SIZE; //更新剩余数据个数
00D6 ; ad_dst+=PAGE_SIZE; //更新剩下数据的起始地址
00D6 ; }
00D6 ;
00D6 ; if(num) //把最后剩下的小于一个PAGE_SIZE长度的数据写入器件
00D6 8030 cpi R24,0
00D8 8907 cpc R24,R25
00DA 29F0 breq L15
00DC X2:
00DC .dbline 99
00DC ; wt24c_fc(p_rsc, ad_dst, num);
00DC C882 std y+0,R12
00DE 9701 movw R18,R14
00E0 0B85 ldd R16,y+11
00E2 1C85 ldd R17,y+12
00E4 2FD0 xcall _wt24c_fc
00E6 L15:
00E6 .dbline 100
00E6 L5:
00E6 .dbline -2
00E6 L1:
00E6 2196 adiw R28,1
00E8 0E940000 xcall pop_gset5
00EC 2496 adiw R28,4
00EE .dbline 0 ; func end
00EE 0895 ret
00F0 .dbsym r n 10 i
00F0 .dbsym r num 12 i
00F0 .dbsym r ad_dst 14 i
00F0 .dbsym l p_rsc 11 pc
00F0 .dbend
00F0 .dbfunc e rd24c _rd24c fV
00F0 ; t -> R10
00F0 ; num -> R22,R23
00F0 ; ad_rsc -> R12,R13
00F0 ; p_dst -> R20,R21
.even
00F0 _rd24c::
00F0 0E940000 xcall push_gset4
00F4 6901 movw R12,R18
00F6 A801 movw R20,R16
00F8 6885 ldd R22,y+8
00FA 7985 ldd R23,y+9
00FC .dbline -1
00FC .dbline 108
00FC ; }
00FC ; }
00FC ;
00FC ;
00FC ; //从24cxx读出数据
00FC ; //参数: *p_dst要读入数据的主机内存地址指针; ad_rsc要输出数据的i2c的地址(整形); num数据个数(整形)
00FC ; //参数条件: ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
00FC ; void rd24c(uchar *p_dst, uint ad_rsc, uint num)
00FC ; { uchar t=0;
00FC .dbline 108
00FC AA24 clr R10
00FE .dbline 111
00FE ;
00FE ; #if e2prom<32
00FE ; t=ad_rsc>>8;
00FE 5601 movw R10,R12
0100 AB2C mov R10,R11
0102 BB24 clr R11
0104 .dbline 112
0104 ; t<<=1;
0104 AA0C lsl R10
0106 .dbline 115
0106 ; #endif
0106 ;
0106 ; i2cstart(); //发送起始信号
0106 45D0 xcall _i2cstart
0108 .dbline 117
0108 ;
0108 ; if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址
0108 0A2D mov R16,R10
010A 0056 subi R16,96 ; addi 160
010C 48D0 xcall _i2cwt
010E 0831 cpi R16,24
0110 91F4 brne L18
0112 .dbline 118
0112 ; {
0112 .dbline 122
0112 ; #if e2prom>16
0112 ; i2cwt(ad_rsc>>8); //ad_rsc的高位, 发送要读出数据的地址
0112 ; #endif
0112 ; i2cwt(ad_rsc); //ad_rsc的低位
0112 0C2D mov R16,R12
0114 44D0 xcall _i2cwt
0116 .dbline 124
0116 ;
0116 ; i2cstart(); //再发送起始信号
0116 3DD0 xcall _i2cstart
0118 .dbline 125
0118 ; i2cwt(R_ADD_COM+t); //发送SLA_R, 读命令字节及器件地址
0118 0A2D mov R16,R10
011A 0F55 subi R16,95 ; addi 161
011C 40D0 xcall _i2cwt
011E .dbline 127
011E ;
011E ; for(;num>0;num--)
011E 07C0 xjmp L23
0120 L20:
0120 .dbline 128
0120 .dbline 128
0120 48D0 xcall _i2crd
0122 FA01 movw R30,R20
0124 0083 std z+0,R16
0126 .dbline 129
0126 4F5F subi R20,255 ; offset = 1
0128 5F4F sbci R21,255
012A .dbline 130
012A L21:
012A .dbline 127
012A 6150 subi R22,1
012C 7040 sbci R23,0
012E L23:
012E .dbline 127
012E 6030 cpi R22,0
0130 6707 cpc R22,R23
0132 B1F7 brne L20
0134 X4:
0134 .dbline 131
0134 ; { *p_dst=i2crd(); //从器件读出一个字节
0134 ; p_dst++;
0134 ; }
0134 ; }
0134 03C0 xjmp L19
0136 L18:
0136 .dbline 132
0136 ; else syserr=ERR_SLAW; //写字节命令及器件地址错或对方无应答
0136 8AE0 ldi R24,10
0138 80930000 sts _syserr,R24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -