📄 019.lst
字号:
(0014)
(0015) #include "iom16v.h"
(0016)
(0017) /*I2C总线主机模式错误处理*/
(0018) void error(unsigned char type) {
(0019)
(0020) switch (type & 0xF8) {
01E3 2F40 MOV R20,R16
01E4 2755 CLR R21
01E5 7F48 ANDI R20,0xF8
01E6 7050 ANDI R21,0
01E7 3340 CPI R20,0x30
01E8 E0E0 LDI R30,0
01E9 075E CPC R21,R30
01EA F0D1 BEQ 0x0205
01EB E380 LDI R24,0x30
01EC E090 LDI R25,0
01ED 1784 CP R24,R20
01EE 0795 CPC R25,R21
01EF F02C BLT 0x01F5
01F0 3240 CPI R20,0x20
01F1 E0E0 LDI R30,0
01F2 075E CPC R21,R30
01F3 F071 BEQ 0x0202
01F4 C015 RJMP 0x020A
01F5 3348 CPI R20,0x38
01F6 E0E0 LDI R30,0
01F7 075E CPC R21,R30
01F8 F089 BEQ 0x020A
01F9 3348 CPI R20,0x38
01FA E0E0 LDI R30,0
01FB 075E CPC R21,R30
01FC F06C BLT 0x020A
01FD 3448 CPI R20,0x48
01FE E0E0 LDI R30,0
01FF 075E CPC R21,R30
0200 F039 BEQ 0x0208
0201 C008 RJMP 0x020A
(0021) case 0x20: /*址址写失败*/
(0022) /*stop 停止*/
(0023) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
0202 E984 LDI R24,0x94
0203 BF86 OUT 0x36,R24
(0024) break;
0204 C005 RJMP 0x020A
(0025) case 0x30: /*数据写失败*/
(0026) /*stop 停止*/
(0027) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
0205 E984 LDI R24,0x94
0206 BF86 OUT 0x36,R24
(0028) break;
0207 C002 RJMP 0x020A
(0029) case 0x38: /*仲裁失败*/
(0030) break;
(0031) case 0x48: /*址址读失败*/
(0032) /*stop 停止*/
(0033) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
0208 E984 LDI R24,0x94
0209 BF86 OUT 0x36,R24
(0034) break;
020A 940E02C1 CALL pop_gset1
020C 9508 RET
_twi_write:
dd --> R20
addr --> R22
020D 940E02BC CALL push_gset2
020F 2F42 MOV R20,R18
0210 2F60 MOV R22,R16
(0035) }
(0036) }
(0037)
(0038) /*I2C总线单字节写入*/
(0039) unsigned char twi_write(unsigned char addr, unsigned char dd) {
(0040)
(0041) TWBR = 2;
0211 E082 LDI R24,2
0212 B980 OUT 0x00,R24
(0042)
(0043) /*start 启动*/
(0044) TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
0213 EA84 LDI R24,0xA4
0214 BF86 OUT 0x36,R24
(0045) while (!(TWCR & (1 << TWINT)));
0215 B626 IN R2,0x36
0216 FE27 SBRS R2,7
0217 CFFD RJMP 0x0215
(0046) if ((TWSR & 0xF8) != 0x08) {
0218 B181 IN R24,0x01
0219 7F88 ANDI R24,0xF8
021A 3088 CPI R24,0x8
021B F021 BEQ 0x0220
(0047) error(TWSR);
021C B101 IN R16,0x01
021D DFC3 RCALL _error
(0048) return 0;
021E 2700 CLR R16
021F C02E RJMP 0x024E
(0049) }
(0050)
(0051) /*SLA_W 芯片地址*/
(0052) TWDR = 0xA0;
0220 EA80 LDI R24,0xA0
0221 B983 OUT 0x03,R24
(0053) TWCR = (1 << TWINT) | (1 << TWEN);
0222 E884 LDI R24,0x84
0223 BF86 OUT 0x36,R24
(0054) while (!(TWCR & (1 << TWINT)));
0224 B626 IN R2,0x36
0225 FE27 SBRS R2,7
0226 CFFD RJMP 0x0224
(0055) if ((TWSR & 0xF8) != 0x18) {
0227 B181 IN R24,0x01
0228 7F88 ANDI R24,0xF8
0229 3188 CPI R24,0x18
022A F021 BEQ 0x022F
(0056) error(TWSR);
022B B101 IN R16,0x01
022C DFB4 RCALL _error
(0057) return 0;
022D 2700 CLR R16
022E C01F RJMP 0x024E
(0058) }
(0059)
(0060) /*addr 操作地址*/
(0061) TWDR = addr;
022F B963 OUT 0x03,R22
(0062) TWCR = (1 << TWINT) | (1 << TWEN);
0230 E884 LDI R24,0x84
0231 BF86 OUT 0x36,R24
(0063) while (!(TWCR & (1 << TWINT)));
0232 B626 IN R2,0x36
0233 FE27 SBRS R2,7
0234 CFFD RJMP 0x0232
(0064) if ((TWSR & 0xF8) != 0x28) {
0235 B181 IN R24,0x01
0236 7F88 ANDI R24,0xF8
0237 3288 CPI R24,0x28
0238 F021 BEQ 0x023D
(0065) error(TWSR);
0239 B101 IN R16,0x01
023A DFA6 RCALL _error
(0066) return 0;
023B 2700 CLR R16
023C C011 RJMP 0x024E
(0067) }
(0068)
(0069) /*dd 写入数据*/
(0070) TWDR = dd;
023D B943 OUT 0x03,R20
(0071) TWCR = (1 << TWINT) | (1 << TWEN);
023E E884 LDI R24,0x84
023F BF86 OUT 0x36,R24
(0072) while (!(TWCR & (1 << TWINT)));
0240 B626 IN R2,0x36
0241 FE27 SBRS R2,7
0242 CFFD RJMP 0x0240
(0073) if ((TWSR & 0xF8) != 0x28) {
0243 B181 IN R24,0x01
0244 7F88 ANDI R24,0xF8
0245 3288 CPI R24,0x28
0246 F021 BEQ 0x024B
(0074) error(TWSR);
0247 B101 IN R16,0x01
0248 DF98 RCALL _error
(0075) return 0;
0249 2700 CLR R16
024A C003 RJMP 0x024E
(0076) }
(0077)
(0078) /*stop 停止*/
(0079) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
024B E984 LDI R24,0x94
024C BF86 OUT 0x36,R24
(0080) return 1;
024D E001 LDI R16,1
024E 940E02B3 CALL pop_gset2
0250 9508 RET
_twi_read:
dd --> R20
addr --> R22
0251 940E02BC CALL push_gset2
0253 01A9 MOVW R20,R18
0254 2F60 MOV R22,R16
(0081) }
(0082)
(0083) /*I2C总线单字节读取*/
(0084) unsigned char twi_read(unsigned char addr, unsigned char *dd) {
(0085)
(0086) TWBR = 2;
0255 E082 LDI R24,2
0256 B980 OUT 0x00,R24
(0087)
(0088) /*start 启动*/
(0089) TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
0257 EA84 LDI R24,0xA4
0258 BF86 OUT 0x36,R24
(0090) while(!(TWCR&(1<<TWINT)));
0259 B626 IN R2,0x36
025A FE27 SBRS R2,7
025B CFFD RJMP 0x0259
(0091) if ((TWSR & 0xF8) != 0x08) {
025C B181 IN R24,0x01
025D 7F88 ANDI R24,0xF8
025E 3088 CPI R24,0x8
025F F021 BEQ 0x0264
(0092) error(TWSR);
0260 B101 IN R16,0x01
0261 DF7F RCALL _error
(0093) return 0;
0262 2700 CLR R16
0263 C04C RJMP 0x02B0
(0094) }
(0095)
(0096) /*SLA_W 芯片地址*/
(0097) TWDR = 0xA0;
0264 EA80 LDI R24,0xA0
0265 B983 OUT 0x03,R24
(0098) TWCR = (1 << TWINT) | (1 << TWEN);
0266 E884 LDI R24,0x84
0267 BF86 OUT 0x36,R24
(0099) while (!(TWCR & (1 << TWINT)));
0268 B626 IN R2,0x36
0269 FE27 SBRS R2,7
026A CFFD RJMP 0x0268
(0100) if ((TWSR & 0xF8) != 0x18) {
026B B181 IN R24,0x01
026C 7F88 ANDI R24,0xF8
026D 3188 CPI R24,0x18
026E F021 BEQ 0x0273
(0101) error(TWSR);
026F B101 IN R16,0x01
0270 DF70 RCALL _error
(0102) return 0;
0271 2700 CLR R16
0272 C03D RJMP 0x02B0
(0103) }
(0104)
(0105) /*addr 操作地址*/
(0106) TWDR = addr;
0273 B963 OUT 0x03,R22
(0107) TWCR = (1 << TWINT) | (1 << TWEN);
0274 E884 LDI R24,0x84
0275 BF86 OUT 0x36,R24
(0108) while (!(TWCR & (1 << TWINT)));
0276 B626 IN R2,0x36
0277 FE27 SBRS R2,7
0278 CFFD RJMP 0x0276
(0109) if ((TWSR & 0xF8) != 0x28) {
0279 B181 IN R24,0x01
027A 7F88 ANDI R24,0xF8
027B 3288 CPI R24,0x28
027C F021 BEQ 0x0281
(0110) error(TWSR);
027D B101 IN R16,0x01
027E DF62 RCALL _error
(0111) return 0;
027F 2700 CLR R16
0280 C02F RJMP 0x02B0
(0112) }
(0113)
(0114) /*start 启动*/
(0115) TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
0281 EA84 LDI R24,0xA4
0282 BF86 OUT 0x36,R24
(0116) while (!(TWCR & (1 << TWINT)));
0283 B626 IN R2,0x36
0284 FE27 SBRS R2,7
0285 CFFD RJMP 0x0283
(0117) if ((TWSR & 0xF8) != 0x10) {
0286 B181 IN R24,0x01
0287 7F88 ANDI R24,0xF8
0288 3180 CPI R24,0x10
0289 F021 BEQ 0x028E
(0118) error(TWSR);
028A B101 IN R16,0x01
028B DF55 RCALL _error
(0119) return 0;
028C 2700 CLR R16
028D C022 RJMP 0x02B0
(0120) }
(0121)
(0122) /*SLA_R 芯片地址*/
(0123) TWDR = 0xA1;
028E EA81 LDI R24,0xA1
028F B983 OUT 0x03,R24
(0124) TWCR = (1 << TWINT) | (1 << TWEN);
0290 E884 LDI R24,0x84
0291 BF86 OUT 0x36,R24
(0125) while (!(TWCR & (1 << TWINT)));
0292 B626 IN R2,0x36
0293 FE27 SBRS R2,7
0294 CFFD RJMP 0x0292
(0126) if ((TWSR & 0xF8) != 0x40) {
0295 B181 IN R24,0x01
0296 7F88 ANDI R24,0xF8
0297 3480 CPI R24,0x40
0298 F021 BEQ 0x029D
(0127) error(TWSR);
0299 B101 IN R16,0x01
029A DF46 RCALL _error
(0128) return 0;
029B 2700 CLR R16
029C C013 RJMP 0x02B0
(0129) }
(0130)
(0131) /*读取数据*/
(0132) TWCR = (1 << TWINT) | (1 << TWEN);
029D E884 LDI R24,0x84
029E BF86 OUT 0x36,R24
(0133) while (!(TWCR & (1 << TWINT)));
029F B626 IN R2,0x36
02A0 FE27 SBRS R2,7
02A1 CFFD RJMP 0x029F
(0134) if ((TWSR & 0xF8) != 0x58) {
02A2 B181 IN R24,0x01
02A3 7F88 ANDI R24,0xF8
02A4 3588 CPI R24,0x58
02A5 F021 BEQ 0x02AA
(0135) error(TWSR);
02A6 B101 IN R16,0x01
02A7 DF39 RCALL _error
(0136) return 0;
02A8 2700 CLR R16
02A9 C006 RJMP 0x02B0
(0137) }
(0138) *dd = TWDR;
02AA B023 IN R2,0x03
02AB 01FA MOVW R30,R20
02AC 8220 STD Z+0,R2
(0139)
(0140) /*stop 停止*/
(0141) TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
02AD E984 LDI R24,0x94
02AE BF86 OUT 0x36,R24
(0142) return 1;
FILE: <library>
02AF E001 LDI R16,1
02B0 940E02B3 CALL pop_gset2
02B2 9508 RET
pop_gset2:
02B3 E0E2 LDI R30,2
02B4 940C02C2 JMP pop
push_gset5:
02B6 92FA ST R15,-Y
02B7 92EA ST R14,-Y
push_gset4:
02B8 92DA ST R13,-Y
02B9 92CA ST R12,-Y
push_gset3:
02BA 92BA ST R11,-Y
02BB 92AA ST R10,-Y
push_gset2:
02BC 937A ST R23,-Y
02BD 936A ST R22,-Y
push_gset1:
02BE 935A ST R21,-Y
02BF 934A ST R20,-Y
02C0 9508 RET
pop_gset1:
02C1 E0E1 LDI R30,1
pop:
02C2 9149 LD R20,Y+
02C3 9159 LD R21,Y+
02C4 FDE0 SBRC R30,0
02C5 9508 RET
02C6 9169 LD R22,Y+
02C7 9179 LD R23,Y+
02C8 FDE1 SBRC R30,1
02C9 9508 RET
02CA 90A9 LD R10,Y+
02CB 90B9 LD R11,Y+
02CC FDE2 SBRC R30,2
02CD 9508 RET
02CE 90C9 LD R12,Y+
02CF 90D9 LD R13,Y+
02D0 FDE3 SBRC R30,3
02D1 9508 RET
02D2 90E9 LD R14,Y+
02D3 90F9 LD R15,Y+
02D4 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -