📄 twi.lst
字号:
00DF 3085 CPI R24,5
00E0 E0E0 LDI R30,0
00E1 079E CPC R25,R30
00E2 F409 BNE 0x00E4
00E3 C046 RJMP 0x012A
00E4 3086 CPI R24,6
00E5 E0E0 LDI R30,0
00E6 079E CPC R25,R30
00E7 F409 BNE 0x00E9
00E8 C053 RJMP 0x013C
00E9 3087 CPI R24,7
00EA E0E0 LDI R30,0
00EB 079E CPC R25,R30
00EC F409 BNE 0x00EE
00ED C07D RJMP 0x016B
00EE C09D RJMP 0x018C
(0074) {
(0075) case ST_START: //START状态检查
(0076) if(status==TW_START)
00EF 3068 CPI R22,0x8
00F0 F439 BNE 0x00F8
(0077) {//发送start信号成功
(0078) TWDR=strTWI.SLA&0xFE; //发送器件地址写SLAW
00F1 91800069 LDS R24,strTWI+1
00F3 7F8E ANDI R24,0xFE
00F4 B983 OUT 0x03,R24
(0079) TWCR=TW_ACT; //触发下一步动作,同时清start发送标志
00F5 E885 LDI R24,0x85
00F6 BF86 OUT 0x36,R24
(0080) }
00F7 C095 RJMP 0x018D
(0081) else
(0082) {//发送start信号出错
(0083) state=ST_FAIL;
00F8 2744 CLR R20
(0084) }
(0085) break;
00F9 C093 RJMP 0x018D
(0086) case ST_SLAW: //SLAW状态检查
(0087) if(status==TW_MT_SLA_ACK)
00FA 3168 CPI R22,0x18
00FB F429 BNE 0x0101
(0088) {//发送器件地址成功
(0089) TWDR=0xab;
00FC EA8B LDI R24,0xAB
00FD B983 OUT 0x03,R24
(0090) TWCR=TW_ACT; //触发下一步动作
00FE E885 LDI R24,0x85
00FF BF86 OUT 0x36,R24
(0091) }
0100 C08C RJMP 0x018D
(0092) else
(0093) {//发送器件地址出错
(0094) state=ST_FAIL;
0101 2744 CLR R20
(0095) }
(0096) break;
0102 C08A RJMP 0x018D
(0097) case ST_WADDR: //ADDR状态检查
(0098) if(status==TW_MT_DATA_ACK)
0103 3268 CPI R22,0x28
0104 F4C9 BNE 0x011E
(0099) {//发送eeprom地址成功
(0100) if (action==TW_READ)
0105 2D8A MOV R24,R10
0106 3081 CPI R24,1
0107 F419 BNE 0x010B
(0101) {//读操作模式
(0102) TWCR=(1<<TWSTA)|TW_ACT; //发送restart信号,下一步将跳到RESTART分支
0108 EA85 LDI R24,0xA5
0109 BF86 OUT 0x36,R24
(0103) }
010A C082 RJMP 0x018D
(0104) else
(0105) {//写操作模式
(0106) TWDR=*strTWI.pBUF++; //写第一个字节
010B 91E0006A LDS R30,strTWI+2
010D 91F0006B LDS R31,strTWI+3
010F 9021 LD R2,Z+
0110 93F0006B STS strTWI+3,R31
0112 93E0006A STS strTWI+2,R30
0114 B823 OUT 0x03,R2
(0107) strTWI.DATALEN--;
0115 9180006C LDS R24,0x6C
0117 5081 SUBI R24,1
0118 9380006C STS 0x6C,R24
(0108) state=ST_WDATA-1; //下一步将跳到WDATA分支
011A E046 LDI R20,6
(0109) TWCR=TW_ACT; //触发下一步动作
011B E885 LDI R24,0x85
011C BF86 OUT 0x36,R24
(0110) }
(0111) }
011D C06F RJMP 0x018D
(0112) else
(0113) {//发送eeprom地址出错
(0114) state=ST_FAIL;
011E 2744 CLR R20
(0115) }
(0116) break;
011F C06D RJMP 0x018D
(0117) case ST_RESTART: //RESTART状态检查,只有读操作模式才能跳到这里
(0118) if(status==TW_REP_START)
0120 3160 CPI R22,0x10
0121 F431 BNE 0x0128
(0119) {//发送restart信号成功
(0120) TWDR=strTWI.SLA; //发器件地址读SLAR
0122 90200069 LDS R2,strTWI+1
0124 B823 OUT 0x03,R2
(0121) TWCR=TW_ACT; //触发下一步动作,同时清start发送标志
0125 E885 LDI R24,0x85
0126 BF86 OUT 0x36,R24
(0122) }
0127 C065 RJMP 0x018D
(0123) else
(0124) {//重发start信号出错
(0125) state=ST_FAIL;
0128 2744 CLR R20
(0126) }
(0127) break;
0129 C063 RJMP 0x018D
(0128) case ST_SLAR: //SLAR状态检查,只有读操作模式才能跳到这里
(0129) if(status==TW_MR_SLA_ACK)
012A 3460 CPI R22,0x40
012B F471 BNE 0x013A
(0130) {//发送器件地址成功
(0131) if (strTWI.DATALEN--)
012C 9020006C LDS R2,0x6C
012E 2D82 MOV R24,R2
012F 5081 SUBI R24,1
0130 9380006C STS 0x6C,R24
0132 2022 TST R2
0133 F019 BEQ 0x0137
(0132) {//多个数据
(0133) TWCR=(1<<TWEA)|TW_ACT; //设定ACK,触发下一步动作
0134 EC85 LDI R24,0xC5
0135 BF86 OUT 0x36,R24
(0134) }
0136 C056 RJMP 0x018D
(0135) else
(0136) {//只有一个数据
(0137) TWCR=TW_ACT; //设定NAK,触发下一步动作
0137 E885 LDI R24,0x85
0138 BF86 OUT 0x36,R24
(0138) }
(0139) }
0139 C053 RJMP 0x018D
(0140) else
(0141) {//发送器件地址出错
(0142) state=ST_FAIL;
013A 2744 CLR R20
(0143) }
(0144) break;
013B C051 RJMP 0x018D
(0145) case ST_RDATA: //读取数据状态检查,只有读操作模式才能跳到这里
(0146) state--; //循环,直到读完指定长度数据
013C 954A DEC R20
(0147) if(status==TW_MR_DATA_ACK)
013D 3560 CPI R22,0x50
013E F4C1 BNE 0x0157
(0148) {//读取数据成功,但不是最后一个数据
(0149) *strTWI.pBUF++=TWDR;
013F B023 IN R2,0x03
0140 91E0006A LDS R30,strTWI+2
0142 91F0006B LDS R31,strTWI+3
0144 9221 ST R2,Z+
0145 93F0006B STS strTWI+3,R31
0147 93E0006A STS strTWI+2,R30
(0150) if (strTWI.DATALEN--)
0149 9020006C LDS R2,0x6C
014B 2D82 MOV R24,R2
014C 5081 SUBI R24,1
014D 9380006C STS 0x6C,R24
014F 2022 TST R2
0150 F019 BEQ 0x0154
(0151) {//还有多个数据
(0152) TWCR=(1<<TWEA)|TW_ACT; //设定ACK,触发下一步动作
0151 EC85 LDI R24,0xC5
0152 BF86 OUT 0x36,R24
(0153) }
0153 C039 RJMP 0x018D
(0154) else
(0155) {//准备读最后一个数据
(0156) TWCR=TW_ACT; //设定NAK,触发下一步动作
0154 E885 LDI R24,0x85
0155 BF86 OUT 0x36,R24
(0157) }
(0158) }
0156 C036 RJMP 0x018D
(0159) else if(status==TW_MR_DATA_NACK)
0157 3568 CPI R22,0x58
0158 F481 BNE 0x0169
(0160) {//已经读完最后一个数据
(0161) *strTWI.pBUF++=TWDR;
0159 B023 IN R2,0x03
015A 91E0006A LDS R30,strTWI+2
015C 91F0006B LDS R31,strTWI+3
015E 9221 ST R2,Z+
015F 93F0006B STS strTWI+3,R31
0161 93E0006A STS strTWI+2,R30
(0162) TWCR=(1<<TWSTO)|TW_ACT; //发送停止信号,不会再产生中断了
0163 E985 LDI R24,0x95
0164 BF86 OUT 0x36,R24
(0163) strTWI.STATUS=TW_OK;
0165 E081 LDI R24,1
0166 93800068 STS strTWI,R24
(0164) }
0168 C024 RJMP 0x018D
(0165) else
(0166) {//读取数据出错
(0167) state=ST_FAIL;
0169 2744 CLR R20
(0168) }
(0169) break;
016A C022 RJMP 0x018D
(0170) case ST_WDATA: //写数据状态检查,只有写操作模式才能跳到这里
(0171) state--; //循环,直到写完指定长度数据
016B 954A DEC R20
(0172) if(status==TW_MT_DATA_ACK)
016C 3268 CPI R22,0x28
016D F4E1 BNE 0x018A
(0173) {//写数据成功
(0174) if (strTWI.DATALEN)
016E 9020006C LDS R2,0x6C
0170 2022 TST R2
0171 F091 BEQ 0x0184
(0175) {//还要写
(0176) TWDR=*strTWI.pBUF++;
0172 91E0006A LDS R30,strTWI+2
0174 91F0006B LDS R31,strTWI+3
0176 9021 LD R2,Z+
0177 93F0006B STS strTWI+3,R31
0179 93E0006A STS strTWI+2,R30
017B B823 OUT 0x03,R2
(0177) strTWI.DATALEN--;
017C 9180006C LDS R24,0x6C
017E 5081 SUBI R24,1
017F 9380006C STS 0x6C,R24
(0178) TWCR=TW_ACT; //触发下一步动作
0181 E885 LDI R24,0x85
0182 BF86 OUT 0x36,R24
(0179) }
0183 C009 RJMP 0x018D
(0180) else
(0181) {//写够了
(0182) TWCR=(1<<TWSTO)|TW_ACT; //发送停止信号,不会再产生中断了
0184 E985 LDI R24,0x95
0185 BF86 OUT 0x36,R24
(0183) strTWI.STATUS=TW_OK;
0186 E081 LDI R24,1
0187 93800068 STS strTWI,R24
(0184) //启动写命令后需要10ms(最大)的编程时间才能真正的把数据记录下来
(0185) //编程期间器件不响应任何命令
(0186) }
(0187) }
0189 C003 RJMP 0x018D
(0188) else
(0189) {//写数据失败
(0190) state=ST_FAIL;
018A 2744 CLR R20
(0191) }
(0192) break;
018B C001 RJMP 0x018D
(0193) default:
(0194) //错误状态
(0195) state=ST_FAIL;
018C 2744 CLR R20
(0196) break;
(0197) }
(0198)
(0199) if (state==ST_FAIL)
018D 2344 TST R20
018E F479 BNE 0x019E
(0200) {//错误处理
(0201) strTWI.FAILCNT++;
018F 9180006E LDS R24,0x6E
0191 5F8F SUBI R24,0xFF
0192 9380006E STS 0x6E,R24
(0202) if (strTWI.FAILCNT<FAIL_MAX)
0194 3184 CPI R24,0x14
0195 F418 BCC 0x0199
(0203) {//重试次数未超出最大值,
(0204) TWCR=(1<<TWSTA)|TW_ACT; //发生错误,启动start信号
0196 EA85 LDI R24,0xA5
0197 BF86 OUT 0x36,R24
(0205) }
0198 C005 RJMP 0x019E
(0206) else
(0207) {//否则停止
(0208) TWCR=(1<<TWSTO)|TW_ACT; //发送停止信号,不会再产生中断了
0199 E985 LDI R24,0x95
019A BF86 OUT 0x36,R24
(0209) strTWI.STATUS=TW_FAIL;
019B E082 LDI R24,2
019C 93800068 STS strTWI,R24
(0210) }
(0211) }
(0212) state++;
019E 9543 INC R20
(0213) strTWI.STATE=state; //保存状态
019F 9340006D STS 0x6D,R20
(0214) }
(0215) else
(0216) {
(0217) //总线错误或从机模式引发的中断,不予处理
(0218) return;
FILE: <library>
01A1 D002 RCALL pop_gset4
01A2 D039 RCALL pop_lset
01A3 9518 RETI
pop_gset4:
01A4 E0E8 LDI R30,0x8
01A5 C00C RJMP pop
push_gset5:
01A6 92FA ST R15,-Y
01A7 92EA ST R14,-Y
push_gset4:
01A8 92DA ST R13,-Y
01A9 92CA ST R12,-Y
push_gset3:
01AA 92BA ST R11,-Y
01AB 92AA ST R10,-Y
push_gset2:
01AC 937A ST R23,-Y
01AD 936A ST R22,-Y
push_gset1:
01AE 935A ST R21,-Y
01AF 934A ST R20,-Y
01B0 9508 RET
pop_gset1:
01B1 E0E1 LDI R30,1
pop:
01B2 9149 LD R20,Y+
01B3 9159 LD R21,Y+
01B4 FDE0 SBRC R30,0
01B5 9508 RET
01B6 9169 LD R22,Y+
01B7 9179 LD R23,Y+
01B8 FDE1 SBRC R30,1
01B9 9508 RET
01BA 90A9 LD R10,Y+
01BB 90B9 LD R11,Y+
01BC FDE2 SBRC R30,2
01BD 9508 RET
01BE 90C9 LD R12,Y+
01BF 90D9 LD R13,Y+
01C0 FDE3 SBRC R30,3
01C1 9508 RET
01C2 90E9 LD R14,Y+
01C3 90F9 LD R15,Y+
01C4 9508 RET
push_lset:
01C5 93FA ST R31,-Y
01C6 93EA ST R30,-Y
01C7 93BA ST R27,-Y
01C8 93AA ST R26,-Y
01C9 939A ST R25,-Y
01CA 938A ST R24,-Y
01CB 933A ST R19,-Y
01CC 932A ST R18,-Y
01CD 931A ST R17,-Y
01CE 930A ST R16,-Y
01CF 929A ST R9,-Y
01D0 928A ST R8,-Y
01D1 927A ST R7,-Y
01D2 926A ST R6,-Y
01D3 925A ST R5,-Y
01D4 924A ST R4,-Y
01D5 923A ST R3,-Y
01D6 922A ST R2,-Y
01D7 921A ST R1,-Y
01D8 920A ST R0,-Y
01D9 B60F IN R0,0x3F
01DA 920A ST R0,-Y
01DB 9508 RET
pop_lset:
01DC 9009 LD R0,Y+
01DD BE0F OUT 0x3F,R0
01DE 9009 LD R0,Y+
01DF 9019 LD R1,Y+
01E0 9029 LD R2,Y+
01E1 9039 LD R3,Y+
01E2 9049 LD R4,Y+
01E3 9059 LD R5,Y+
01E4 9069 LD R6,Y+
01E5 9079 LD R7,Y+
01E6 9089 LD R8,Y+
01E7 9099 LD R9,Y+
01E8 9109 LD R16,Y+
01E9 9119 LD R17,Y+
01EA 9129 LD R18,Y+
01EB 9139 LD R19,Y+
01EC 9189 LD R24,Y+
01ED 9199 LD R25,Y+
01EE 91A9 LD R26,Y+
01EF 91B9 LD R27,Y+
01F0 91E9 LD R30,Y+
01F1 91F9 LD R31,Y+
01F2 9508 RET
_putchar:
01F3 DFBA RCALL push_gset1
01F4 2F40 MOV R20,R16
01F5 9020006F LDS R2,_textmode
01F7 90300070 LDS R3,_textmode+1
01F9 2022 TST R2
01FA F411 BNE 0x01FD
01FB 2033 TST R3
01FC F021 BEQ 0x0201
01FD 304A CPI R20,0xA
01FE F411 BNE 0x0201
01FF E00D LDI R16,0xD
0200 DFF2 RCALL _putchar
0201 9B5D SBIS 0x0B,5
0202 CFFE RJMP 0x0201
0203 B94C OUT 0x0C,R20
0204 2F04 MOV R16,R20
0205 2711 CLR R17
0206 DFAA RCALL pop_gset1
0207 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -