📄 m16_twi_24cx.lst
字号:
(0141) //返回写入n个字节后的主机内存指针
(0142) uchar * wt24c_fc(uchar *p, uint ad, uchar n)
(0143) { uchar t=0;
00F2 24CC CLR R12
(0144)
(0145) #if e2prom<32
(0146) t=ad>>8;
00F3 0165 MOVW R12,R10
00F4 2CCD MOV R12,R13
00F5 24DD CLR R13
(0147) t<<=1;
00F6 0CCC LSL R12
(0148) #endif
(0149)
(0150) i2cstart(); //发送起始信号
00F7 D01C RCALL _i2cstart
(0151)
(0152) if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址
00F8 2D0C MOV R16,R12
00F9 5600 SUBI R16,0x60
00FA D01F RCALL _i2cwt
00FB 3108 CPI R16,0x18
00FC F469 BNE 0x010A
(0153) {
(0154) #if e2prom>16
(0155) i2cwt(ad>>8); //ad_dst的高位到器件
(0156) #endif
(0157) i2cwt(ad); //ad_dst的低位到器件
00FD 2D0A MOV R16,R10
00FE D01B RCALL _i2cwt
(0158)
(0159) for(;n>0;n--) //发送要写入的数据
00FF C006 RJMP 0x0106
(0160) { i2cwt(*p);
0100 01FA MOVW R30,R20
0101 8100 LDD R16,Z+0
0102 D017 RCALL _i2cwt
(0161) p++;
0103 5F4F SUBI R20,0xFF
0104 4F5F SBCI R21,0xFF
0105 956A DEC R22
0106 2422 CLR R2
0107 1626 CP R2,R22
0108 F3B8 BCS 0x0100
(0162) }
(0163) }
0109 C003 RJMP 0x010D
(0164) else syserr=ERR_SLAW; //写字节命令及器件地址错
010A E08A LDI R24,0xA
010B 93800126 STS syserr,R24
(0165)
(0166) i2cstop();
010D D01D RCALL _i2cstop
(0167) tms(6); //延时6ms
010E E006 LDI R16,6
010F D02D RCALL _tms
(0168)
(0169) return(p);
0110 018A MOVW R16,R20
0111 940E0261 CALL pop_gset4
0113 9508 RET
(0170) }
(0171)
(0172)
(0173)
(0174) //-------------------------------以下为其它I2总线器件可调用的函数--------------------------
(0175)
(0176) //总线上起动开始条件
(0177) void i2cstart(void)
(0178) {
(0179) TWCR= BIT(TWINT) | BIT(TWSTA) | BIT(TWEN);
_i2cstart:
0114 EA84 LDI R24,0xA4
0115 BF86 OUT 0x36,R24
(0180) while (!(TWCR & BIT(TWINT)));
0116 B626 IN R2,0x36
0117 FE27 SBRS R2,7
0118 CFFD RJMP 0x0116
0119 9508 RET
(0181) }
(0182)
(0183) //把一个字节数据输入器件, 返回TWI状态
(0184) uchar i2cwt(uchar a)
(0185) {
(0186) TWDR = a;
_i2cwt:
a --> R16
011A B903 OUT 0x03,R16
(0187) TWCR = BIT(TWINT) | BIT(TWEN);
011B E884 LDI R24,0x84
011C BF86 OUT 0x36,R24
(0188) while (!(TWCR & BIT(TWINT)));
011D B626 IN R2,0x36
011E FE27 SBRS R2,7
011F CFFD RJMP 0x011D
(0189) _NOP();
0120 0000 NOP
(0190) return(TWSR&0b11111000);
0121 B101 IN R16,0x01
0122 7F08 ANDI R16,0xF8
0123 9508 RET
(0191) }
(0192)
(0193) //i2c读要调用的函数
(0194) //从器件读出一个字节
(0195) uchar i2crd(void)
(0196) {
(0197) TWCR= BIT(TWINT) | BIT(TWEA) | BIT(TWEN);
_i2crd:
0124 EC84 LDI R24,0xC4
0125 BF86 OUT 0x36,R24
(0198) while (!(TWCR & BIT(TWINT)));
0126 B626 IN R2,0x36
0127 FE27 SBRS R2,7
0128 CFFD RJMP 0x0126
(0199) return(TWDR);
0129 B103 IN R16,0x03
012A 9508 RET
(0200) }
(0201)
(0202)
(0203) //总线上起动停止条件
(0204) void i2cstop(void)
(0205) {
(0206) TWCR = BIT(TWINT) | BIT(TWSTO) | BIT(TWEN);
_i2cstop:
012B E984 LDI R24,0x94
012C BF86 OUT 0x36,R24
012D 9508 RET
_Delay100us:
i --> R20
x --> R16
012E 940E026F CALL push_gset1
(0207) }
(0208) //************************************************************************/
(0209) //延时函数 古欣添加
(0210) void Delay100us(uchar x)
(0211) {
(0212) uchar i; //4clock
(0213) for(i=147;x!=0;x--)
0130 E943 LDI R20,0x93
0131 C006 RJMP 0x0138
(0214) while(--i); //5 * i clock
0132 2F84 MOV R24,R20
0133 5081 SUBI R24,1
0134 2F48 MOV R20,R24
0135 2388 TST R24
0136 F7D9 BNE 0x0132
0137 950A DEC R16
0138 2300 TST R16
0139 F7C1 BNE 0x0132
013A 940E0272 CALL pop_gset1
013C 9508 RET
_tms:
n --> R20
013D 940E026F CALL push_gset1
013F 2F40 MOV R20,R16
(0215) }
(0216) void tms(uchar n)
(0217) {
(0218) for (;n!=0;n--){
0140 C003 RJMP 0x0144
(0219) Delay100us(10);
0141 E00A LDI R16,0xA
0142 DFEB RCALL _Delay100us
0143 954A DEC R20
0144 2344 TST R20
0145 F7D9 BNE 0x0141
0146 940E0272 CALL pop_gset1
0148 9508 RET
_Delay1s:
m --> R20
0149 940E026F CALL push_gset1
014B 01A8 MOVW R20,R16
(0220) }
(0221) }
(0222) void Delay1s(uint m) // m <= 6 ,when m==7, it is 1.
(0223) {
(0224) m=m*40;
014C E208 LDI R16,0x28
014D E010 LDI R17,0
014E 019A MOVW R18,R20
014F 940E0221 CALL empy16s
0151 01A8 MOVW R20,R16
(0225) for (;m!=0;m--){
0152 C004 RJMP 0x0157
(0226) Delay100us(250);
0153 EF0A LDI R16,0xFA
0154 DFD9 RCALL _Delay100us
0155 5041 SUBI R20,1
0156 4050 SBCI R21,0
0157 3040 CPI R20,0
0158 0745 CPC R20,R21
0159 F7C9 BNE 0x0153
015A 940E0272 CALL pop_gset1
015C 9508 RET
_main:
y --> R14
x --> R10
w --> R12
b --> R20
r --> R22
c --> Y+4
i --> Y+2
015D 9726 SBIW R28,6
FILE: E:\avr\m16_twi_24x\24CxxMain.c
(0001) #include<iom16v.h>
(0002) #include<macros.h>
(0003) #include"xd.h"
(0004) #define XDmain
(0005) #include"xdprj.h"
(0006)
(0007)
(0008) uchar r_buf[64];
(0009)
(0010) uchar w_buf[64];
(0011)
(0012) void main()
(0013) {
(0014) uint i;
(0015)
(0016) uchar *r;
(0017) uint b;
(0018) uint c;
(0019)
(0020) uchar *w;
(0021) uint x;
(0022) uint y;
(0023)
(0024) tms(100);
015E E604 LDI R16,0x64
015F 940E013D CALL _tms
(0025)
(0026) //-----初始化cpu------
(0027) setreg_m16(); //初始化cpu
0161 D0A3 RCALL _setreg_m16
(0028)
(0029)
(0030) for(i=0;i<64;i++) //清主机读和写缓存区
0162 2400 CLR R0
0163 2411 CLR R1
0164 821B STD Y+3,R1
0165 820A STD Y+2,R0
0166 C014 RJMP 0x017B
(0031) r_buf[i]=w_buf[i]=0;
0167 E680 LDI R24,0x60
0168 E090 LDI R25,0
0169 81EA LDD R30,Y+2
016A 81FB LDD R31,Y+3
016B 0FE8 ADD R30,R24
016C 1FF9 ADC R31,R25
016D 2422 CLR R2
016E 8220 STD Z+0,R2
016F EA80 LDI R24,0xA0
0170 E090 LDI R25,0
0171 81EA LDD R30,Y+2
0172 81FB LDD R31,Y+3
0173 0FE8 ADD R30,R24
0174 1FF9 ADC R31,R25
0175 8220 STD Z+0,R2
0176 818A LDD R24,Y+2
0177 819B LDD R25,Y+3
0178 9601 ADIW R24,1
0179 839B STD Y+3,R25
017A 838A STD Y+2,R24
017B 818A LDD R24,Y+2
017C 819B LDD R25,Y+3
017D 3480 CPI R24,0x40
017E E0E0 LDI R30,0
017F 079E CPC R25,R30
0180 F330 BCS 0x0167
(0032)
(0033) for(i=0;i<64;i++) //写缓存区赋初值
0181 2400 CLR R0
0182 2411 CLR R1
0183 821B STD Y+3,R1
0184 820A STD Y+2,R0
0185 C00E RJMP 0x0194
(0034) w_buf[i]=i;
0186 E680 LDI R24,0x60
0187 E090 LDI R25,0
0188 81EA LDD R30,Y+2
0189 81FB LDD R31,Y+3
018A 0FE8 ADD R30,R24
018B 1FF9 ADC R31,R25
018C 802A LDD R2,Y+2
018D 803B LDD R3,Y+3
018E 8220 STD Z+0,R2
018F 818A LDD R24,Y+2
0190 819B LDD R25,Y+3
0191 9601 ADIW R24,1
0192 839B STD Y+3,R25
0193 838A STD Y+2,R24
0194 818A LDD R24,Y+2
0195 819B LDD R25,Y+3
0196 3480 CPI R24,0x40
0197 E0E0 LDI R30,0
0198 079E CPC R25,R30
0199 F360 BCS 0x0186
(0035)
(0036) r=r_buf; //读参数
019A EA60 LDI R22,0xA0
019B E070 LDI R23,0
(0037) b=0x00;
019C 2744 CLR R20
019D 2755 CLR R21
(0038) c=64;
019E E480 LDI R24,0x40
019F E090 LDI R25,0
01A0 839D STD Y+5,R25
01A1 838C STD Y+4,R24
(0039)
(0040) w=w_buf; //写参数
01A2 E680 LDI R24,0x60
01A3 E090 LDI R25,0
01A4 016C MOVW R12,R24
(0041) x=0x00;
01A5 24AA CLR R10
01A6 24BB CLR R11
(0042) y=64;
01A7 E480 LDI R24,0x40
01A8 E090 LDI R25,0
01A9 017C MOVW R14,R24
(0043)
(0044) wt24c(w,x,y); //写
01AA 82F9 STD Y+1,R15
01AB 82E8 STD Y+0,R14
01AC 0195 MOVW R18,R10
01AD 0186 MOVW R16,R12
01AE 940E004B CALL _wt24c
(0045)
(0046) rd24c(r,b,c); //读
01B0 800C LDD R0,Y+4
01B1 801D LDD R1,Y+5
01B2 8219 STD Y+1,R1
01B3 8208 STD Y+0,R0
01B4 019A MOVW R18,R20
01B5 018B MOVW R16,R22
01B6 940E00C3 CALL _rd24c
(0047)
(0048) //-----读出的数据发送到PC-----
(0049) for(i=0;i<64;i++)
01B8 2400 CLR R0
01B9 2411 CLR R1
01BA 821B STD Y+3,R1
01BB 820A STD Y+2,R0
01BC C013 RJMP 0x01D0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -