📄 twi_1.s
字号:
cpc R5,R3
brsh L59
.dbline 309
; {
.dbline 311
; // 发送数据
; i2cSendByte( *(I2cSendData+I2cSendDataIndex) );
lds R2,_I2cSendData
lds R3,_I2cSendData+1
movw R30,R4
add R30,R2
adc R31,R3
ldd R16,z+0
xcall _i2cSendByte
.dbline 312
; I2cSendDataIndex++;
lds R24,_I2cSendDataIndex
lds R25,_I2cSendDataIndex+1
adiw R24,1
sts _I2cSendDataIndex+1,R25
sts _I2cSendDataIndex,R24
.dbline 313
; }
xjmp L55
L59:
.dbline 315
; else
; {
.dbline 317
; // 发送停止条件,保持TWEA以便从接收
; i2cSendStop();
xcall _i2cSendStop
.dbline 319
; // 设置状态
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 320
; }
.dbline 321
; break;
xjmp L55
L61:
.dbline 325
; case TW_MR_DATA_NACK: // 0x58: 接收到数据;NOT ACK 已返回
;
; // 保存最终数据
; *(I2cReceiveData+I2cReceiveDataIndex) = TWDR;
lds R2,_I2cReceiveData
lds R3,_I2cReceiveData+1
lds R30,_I2cReceiveDataIndex
lds R31,_I2cReceiveDataIndex+1
add R30,R2
adc R31,R3
in R2,0x3
std z+0,R2
.dbline 326
; I2cReceiveDataIndex++;
lds R24,_I2cReceiveDataIndex
lds R25,_I2cReceiveDataIndex+1
adiw R24,1
sts _I2cReceiveDataIndex+1,R25
sts _I2cReceiveDataIndex,R24
L62:
.dbline 333
; //继续发送条件
; case TW_MR_SLA_NACK: // 0x48: SLA+R 已发送,接收到NOT ACK
; case TW_MT_SLA_NACK: // 0x20: SLA+W 已发送,接收到NOT ACK
; case TW_MT_DATA_NACK: // 0x30: 数据已发送,接收到NOT ACK
;
; // 发送停止条件,保持TWEA以便从接收
; i2cSendStop();
xcall _i2cSendStop
.dbline 336
; // 设置状态
; // if(status == TW_MR_SLA_NACK || status == TW_MT_SLA_NACK) /*此行有效则,数据发送过程中的模块断开不进行报错处理*/
; I2cNotAck = 0xff;
ldi R24,255
sts _I2cNotAck,R24
.dbline 337
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 338
; break;
xjmp L55
L63:
.dbline 343
; case TW_MT_ARB_LOST: // 0x38: SLA+W 或数据的仲裁失败
;
;
; // 释放总线
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT);
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
.dbline 345
; // 设置状态
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 347
;
; break;
xjmp L55
L64:
.dbline 351
; case TW_MR_DATA_ACK: // 0x50: 接收到数据,ACK 已返回
;
; // 保存接收到的数据位
; *(I2cReceiveData+I2cReceiveDataIndex) = TWDR;
lds R2,_I2cReceiveData
lds R3,_I2cReceiveData+1
lds R30,_I2cReceiveDataIndex
lds R31,_I2cReceiveDataIndex+1
add R30,R2
adc R31,R3
in R2,0x3
std z+0,R2
.dbline 352
; I2cReceiveDataIndex++;
lds R24,_I2cReceiveDataIndex
lds R25,_I2cReceiveDataIndex+1
adiw R24,1
sts _I2cReceiveDataIndex+1,R25
sts _I2cReceiveDataIndex,R24
L65:
.dbline 356
; // 检查是否接收完
; case TW_MR_SLA_ACK: // 0x40: SLA+R 已发送,接收到ACK
;
; if(I2cReceiveDataIndex < I2cReceiveDataLength )
lds R2,_I2cReceiveDataLength
lds R3,_I2cReceiveDataLength+1
lds R4,_I2cReceiveDataIndex
lds R5,_I2cReceiveDataIndex+1
cp R4,R2
cpc R5,R3
brsh L66
.dbline 357
; {
.dbline 358
; i2cReceiveByte(TRUE);
ldi R16,1
xcall _i2cReceiveByte
.dbline 359
; }
xjmp L55
L66:
.dbline 360
; else if(I2cReceiveDataIndex < 3 && EnFlex) //仅限于数据帧前两个字节是长度的情况
lds R24,_I2cReceiveDataIndex
lds R25,_I2cReceiveDataIndex+1
cpi R24,3
ldi R30,0
cpc R25,R30
brsh L68
lds R2,_EnFlex
tst R2
breq L68
.dbline 361
; {
.dbline 362
; if(I2cReceiveDataIndex == 2)
cpi R24,2
ldi R30,0
cpc R25,R30
brne L70
.dbline 363
; {
.dbline 364
; I2cReceiveDataLength = *((unsigned int*)I2cReceiveData);
lds R30,_I2cReceiveData
lds R31,_I2cReceiveData+1
ldd R2,z+0
ldd R3,z+1
sts _I2cReceiveDataLength+1,R3
sts _I2cReceiveDataLength,R2
.dbline 365
; }
L70:
.dbline 367
; // 数据位将接收 , 回复 ACK (传送更多字节)
; i2cReceiveByte(TRUE);
ldi R16,1
xcall _i2cReceiveByte
.dbline 368
; }
xjmp L55
L68:
.dbline 370
; else
; {
.dbline 372
; // 数据位将接收 , 回复 NACK (传送最后字节)
; i2cReceiveByte(FALSE);
clr R16
xcall _i2cReceiveByte
.dbline 373
; }
.dbline 374
; break;
xjmp L55
L72:
.dbline 384
;
; // 从接收状态码
; case TW_SR_SLA_ACK: // 0x60: 自己的SLA+W 已经被接收,ACK 已返回
; case TW_SR_ARB_LOST_SLA_ACK:// 0x68: SLA+R/W 作为主机的仲裁失败;自己的SLA+W 已经被接收,ACK 已返回
; case TW_SR_GCALL_ACK: // 0x70: 接收到广播地址,ACK 已返回
; case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: SLA+R/W 作为主机的仲裁失败;接收到广播地址,ACK 已返回
;
; // 被选中为从写入 (数据将从主机接收)
; // 设置状态
; I2cState = I2C_SLAVE_RX;
ldi R24,5
sts _I2cState,R24
.dbline 386
; // 缓冲准备
; I2cReceiveDataIndex = 0;
clr R2
clr R3
sts _I2cReceiveDataIndex+1,R3
sts _I2cReceiveDataIndex,R2
.dbline 388
; // 接收数据,回应 ACK
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 389
; break;
xjmp L55
L73:
.dbline 394
; case TW_SR_DATA_ACK: // 0x80: 以前以自己的 SLA+W 被寻址;数据已经被接收,ACK 已返回
; case TW_SR_GCALL_DATA_ACK: // 0x90: 以前以广播方式被寻址;数据已经被接收,ACK 已返回
;
;
; *(I2cReceiveData+I2cReceiveDataIndex) = TWDR;
lds R2,_I2cReceiveData
lds R3,_I2cReceiveData+1
lds R30,_I2cReceiveDataIndex
lds R31,_I2cReceiveDataIndex+1
add R30,R2
adc R31,R3
in R2,0x3
std z+0,R2
.dbline 395
; I2cReceiveDataIndex++;
lds R24,_I2cReceiveDataIndex
lds R25,_I2cReceiveDataIndex+1
adiw R24,1
sts _I2cReceiveDataIndex+1,R25
sts _I2cReceiveDataIndex,R24
.dbline 397
; //检查接收缓冲区状态
; if(I2cReceiveDataIndex < SR_DATA_LENGTH_MAX)
cpi R24,5
ldi R30,2
cpc R25,R30
brsh L74
.dbline 398
; {
.dbline 400
; // 接收数据,回应 ACK
; i2cReceiveByte(TRUE);
ldi R16,1
xcall _i2cReceiveByte
.dbline 401
; }
xjmp L55
L74:
.dbline 403
; else
; {
.dbline 405
; // 接收数据,回应 NACK
; i2cReceiveByte(FALSE);
clr R16
xcall _i2cReceiveByte
.dbline 406
; }
.dbline 407
; break;
xjmp L55
L76:
.dbline 412
; case TW_SR_DATA_NACK: // 0x88: 以前以自己的 SLA+W 被寻址;数据已经被接收,NOT ACK 已返回
; case TW_SR_GCALL_DATA_NACK: // 0x98: 以前以广播方式被寻址;数据已经被接收,NOT ACK 已返回
;
; // 接收数据,回应 NACK
; i2cReceiveByte(FALSE);
clr R16
xcall _i2cReceiveByte
.dbline 413
; break;
xjmp L55
L77:
.dbline 415
; case TW_SR_STOP: // 0xA0: 在以从机工作时接收到STOP或重复START
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 417
; // 设置状态
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 418
; SET_REC_COM;
lds R24,_I2cComStatus
ori R24,128
sts _I2cComStatus,R24
.dbline 419
; break;
xjmp L55
L78:
.dbline 427
;
; // 从发送
; case TW_ST_SLA_ACK: // 0xA8: 自己的SLA+R 已经被接收,ACK 已返回
; case TW_ST_ARB_LOST_SLA_ACK:// 0xB0: SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收,ACK 已返回
;
; // 被选中为从读出 (数据将从传回主机)
; // 设置状态
; I2cState = I2C_SLAVE_TX;
ldi R24,4
sts _I2cState,R24
.dbline 429
; // 数据请求
; I2cSendDataLength = *SlaveSendLength;
lds R30,_SlaveSendLength
lds R31,_SlaveSendLength+1
ldd R2,z+0
ldd R3,z+1
sts _I2cSendDataLength+1,R3
sts _I2cSendDataLength,R2
.dbline 430
; I2cSendDataIndex = 0;
clr R2
clr R3
sts _I2cSendDataIndex+1,R3
sts _I2cSendDataIndex,R2
L79:
.dbline 435
; //
; case TW_ST_DATA_ACK: // 0xB8: TWDR 里数据已经发送,接收到ACK
;
; // 发送数据位
; TWDR = *(I2cSendData+I2cSendDataIndex);
lds R2,_I2cSendData
lds R3,_I2cSendData+1
lds R30,_I2cSendDataIndex
lds R31,_I2cSendDataIndex+1
add R30,R2
adc R31,R3
ldd R2,z+0
out 0x3,R2
.dbline 436
; I2cSendDataIndex++;
lds R24,_I2cSendDataIndex
lds R25,_I2cSendDataIndex+1
adiw R24,1
sts _I2cSendDataIndex+1,R25
sts _I2cSendDataIndex,R24
.dbline 437
; if(I2cSendDataIndex < I2cSendDataLength)
lds R2,_I2cSendDataLength
lds R3,_I2cSendDataLength+1
cp R24,R2
cpc R25,R3
brsh L80
.dbline 439
; // 回应 ACK
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
xjmp L55
L80:
.dbline 442
; else
; // 回应 NACK
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT);
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
.dbline 443
; break;
xjmp L55
L82:
.dbline 449
; case TW_ST_DATA_NACK: // 0xC0: TWDR 里数据已经发送接收到NOT ACK
; case TW_ST_LAST_DATA: // 0xC8: TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK
;
; // 全部完成
; // 从方式开放
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 451
; // 设置状态
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 452
; break;
xjmp L55
X3:
.dbline 458
;
;
; case TW_NO_INFO: // 0xF8: 没有相关的状态信息;TWINT = “0”
; // 无操作
;
; break;
L84:
.dbline 462
; case TW_BUS_ERROR: // 0x00: 由于非法的START 或STOP 引起的总线错误
;
; // 内部硬件复位,释放总线
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWSTO)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,208
out 0x36,R24
.dbline 464
; // 设置状态
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 465
; break;
L54:
L55:
.dbline -2
L53:
xcall pop_gset1
xcall pop_lset
.dbline 0 ; func end
reti
.dbsym r status 20 c
.dbend
.dbfunc e testI2cMemory _testI2cMemory fV
; rxdata -> y+68
; txdata -> y+2
; i -> R20
.even
_testI2cMemory::
xcall push_gset1
sbiw R28,63
sbiw R28,63
sbiw R28,8 ; offset = 134
.dbline -1
.dbline 472
; }
; }
;
; #define TARGET_ADDR 0xA0
; //测试 (24xxyy 器件)
; void testI2cMemory(void)
; {
.dbline 477
; unsigned char i;
; unsigned char txdata[66];
; unsigned char rxdata[66];
;
; txdata[0] = 0;
clr R2
std y+2,R2
.dbline 478
; txdata[1] = 0;
std y+3,R2
.dbline 480
;
; for(i=0; i<16; i++)
clr R20
xjmp L116
L113:
.dbline 481
ldi R24,<_localBuffer
ldi R25,>_localBuffer
mov R30,R20
clr R31
add R30,R24
adc R31,R25
ldd R2,z+0
movw R24,R28
adiw R24,4
mov R30,R20
clr R31
add R30,R24
adc R31,R25
std z+0,R2
L114:
.dbline 480
inc R20
L116:
.dbline 480
cpi R20,16
brlo L113
.dbline 483
; txdata[2+i] = localBuffer[i];
; // 发送地址和数据
; i2cMasterSendNI(TARGET_ADDR, 18, txdata);
movw R24,R28
adiw R24,2
std y+1,R25
std y+0,R24
ldi R18,18
ldi R16,160
xcall _i2cMasterSendNI
.dbline 486
;
;
; txdata[18] = 0;
clr R2
std y+20,R2
.dbline 489
;
; // 发送地址
; i2cMasterSendNI(TARGET_ADDR, 2, txdata);
movw R24,R28
adiw R24,2
std y+1,R25
std y+0,R24
ldi R18,2
ldi R16,160
xcall _i2cMasterSendNI
.dbline 491
; // 接收数据
; i2cMasterReceiveNI(TARGET_ADDR, 16, rxdata);
movw R24,R28
subi R24,188 ; offset = 68
sbci R25,255
std y+1,R25
std y+0,R24
ldi R18,16
ldi R16,160
xcall _i2cMasterReceiveNI
.dbline 493
; //
; rxdata[16] = 0;
clr R2
movw R30,R28
subi R30,172 ; addi 84
sbci R31,255
std z+0,R2
.dbline -2
L111:
adiw R28,63
adiw R28,63
adiw R28,8 ; offset = 134
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym l rxdata 68 A[66:66]c
.dbsym l txdata 2 A[66:66]c
.dbsym r i 20 c
.dbend
.area bss(ram, con, rel)
.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827\twi_1.c
_SlaveSendLength::
.blkb 2
.dbsym e SlaveSendLength _SlaveSendLength pi
_I2cComStatus::
.blkb 1
.dbsym e I2cComStatus _I2cComStatus c
_I2cReceiveDataLength:
.blkb 2
.dbsym s I2cReceiveDataLength _I2cReceiveDataLength i
_I2cReceiveDataIndex:
.blkb 2
.dbsym s I2cReceiveDataIndex _I2cReceiveDataIndex i
_I2cReceiveData::
.blkb 2
.dbsym e I2cReceiveData _I2cReceiveData pc
_I2cSendDataLength:
.blkb 2
.dbsym s I2cSendDataLength _I2cSendDataLength i
_I2cSendDataIndex:
.blkb 2
.dbsym s I2cSendDataIndex _I2cSendDataIndex i
_I2cSendData::
.blkb 2
.dbsym e I2cSendData _I2cSendData pc
_I2cDeviceAddrRW:
.blkb 1
.dbsym s I2cDeviceAddrRW _I2cDeviceAddrRW c
_I2cState:
.blkb 1
.dbsym s I2cState _I2cState c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -