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

📄 24cxx.lis

📁 一个关于AVR单片机的例程
💻 LIS
📖 第 1 页 / 共 2 页
字号:
                        .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 + -