📄 twi.s
字号:
.module twi.c
.area data(ram, con, rel)
_main_tmp::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile F:\2007电子设计\古欣\twitest\twi_slave_test\twi.c
.dbsym e main_tmp _main_tmp c
.area text(rom, con, rel)
.dbfile F:\2007电子设计\古欣\twitest\twi_slave_test\twi.c
.dbfunc e twi_master_init _twi_master_init fV
.even
_twi_master_init::
.dbline -1
.dbline 9
; #include "config.h"
;
; volatile uint8 main_tmp=0;
; //extern volatile uint8 main_tmp=0;
;
; //TWI master initialize
; // bit rate:100
; void twi_master_init(void)
; {
.dbline 10
; TWCR= 0x00; //disable twi
clr R2
out 0x36,R2
.dbline 11
; TWBR= 0x64; //set bit rate
ldi R24,100
out 0x0,R24
.dbline 12
; TWSR= 0x00; //set prescale
out 0x1,R2
.dbline 13
; TWAR= 0x00; //set slave address
out 0x2,R2
.dbline 14
; TWCR= 0x04; //enable twi
ldi R24,4
out 0x36,R24
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.dbfunc e twi_slave_init _twi_slave_init fV
; add -> R16
.even
_twi_slave_init::
.dbline -1
.dbline 20
; }
;
; //TWI slave initialize
; // bit rate:100
; void twi_slave_init(uint8 add)
; {
.dbline 21
; TWCR= 0x00; //disable twi
clr R2
out 0x36,R2
.dbline 22
; TWBR= 0x64; //set bit rate
ldi R24,100
out 0x0,R24
.dbline 23
; TWSR= 0x00; //set prescale
out 0x1,R2
.dbline 24
; TWAR= add; //set slave address 从机地址为 0x01
out 0x2,R16
.dbline 25
; TWCR= (1<<TWEN)|(1<<TWEA)|(1<<TWIE); //enable twi
ldi R24,69
out 0x36,R24
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbsym r add 16 c
.dbend
.dbfunc e i2c_start _i2c_start fV
.even
_i2c_start::
.dbline -1
.dbline 31
; //TWEN必须置位以使能TWI接口。TWEA也要置位以使主机寻址到自己(从机地址或广播) 时返回确认信息ACK
; }
;
; //总线上起动开始条件
; void i2c_start(void)
; {
.dbline 32
; TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
ldi R24,164
out 0x36,R24
L4:
.dbline 33
L5:
.dbline 33
; while (!(TWCR & (1<<TWINT))); //等待START 信号成功发送
in R2,0x36
sbrs R2,7
rjmp L4
.dbline -2
L3:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2c_write _i2c_write fc
; data -> R16
.even
_i2c_write::
.dbline -1
.dbline 39
; }
;
; //把一个字节数据输入器件, 返回TWI状态
; //发送地址和数据都可以使用本函数
; uint8 i2c_write(uint8 data)
; {
.dbline 40
; TWDR = data;
out 0x3,R16
.dbline 41
; TWCR = (1<<TWINT)|(1<<TWEN);
ldi R24,132
out 0x36,R24
L8:
.dbline 42
L9:
.dbline 42
; while (!(TWCR & (1<<TWINT)));
in R2,0x36
sbrs R2,7
rjmp L8
.dbline 43
; _NOP();
nop
.dbline 44
; return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
in R16,0x1
andi R16,248
.dbline -2
L7:
.dbline 0 ; func end
ret
.dbsym r data 16 c
.dbend
.dbfunc e i2c_read _i2c_read fc
.even
_i2c_read::
.dbline -1
.dbline 49
; }
;
; //从器件读出一个字节
; uint8 i2c_read(void)
; {
.dbline 50
; TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
ldi R24,196
out 0x36,R24
L12:
.dbline 51
L13:
.dbline 51
; while (!(TWCR & (1<<TWINT)));
in R2,0x36
sbrs R2,7
rjmp L12
.dbline 52
; return(TWDR);
in R16,0x3
.dbline -2
L11:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2c_stop _i2c_stop fV
.even
_i2c_stop::
.dbline -1
.dbline 57
; }
;
; //总线上起动停止条件
; void i2c_stop(void)
; {
.dbline 58
; TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
ldi R24,148
out 0x36,R24
.dbline -2
L15:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2c_maste_transt _i2c_maste_transt fV
; data -> R20
; addr -> R22
.even
_i2c_maste_transt::
xcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 63
; }
;
; //操作步骤: 启动,发送地址,发送数据,关闭总线
; void i2c_maste_transt(uint8 addr, uint8 data)
; {
.dbline 64
; i2c_start();
xcall _i2c_start
.dbline 65
; if(i2c_write(addr)==TW_MT_SLA_ACK) //发送地址成功并收到ACK
mov R16,R22
xcall _i2c_write
cpi R16,24
brne L17
.dbline 66
; {
.dbline 67
; i2c_write(data);
mov R16,R20
xcall _i2c_write
.dbline 68
; }
L17:
.dbline 69
; i2c_stop();
xcall _i2c_stop
.dbline -2
L16:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r data 20 c
.dbsym r addr 22 c
.dbend
.area vector(rom, abs)
.org 68
jmp _twi_isr
.area text(rom, con, rel)
.dbfile F:\2007电子设计\古欣\twitest\twi_slave_test\twi.c
.dbfunc e twi_isr _twi_isr fV
.even
_twi_isr::
xcall push_lset
xcall push_gset1
.dbline -1
.dbline 75
; }
;
; #if TWI_MOD==0 //从机模式
; #pragma interrupt_handler twi_isr:18
; void twi_isr(void)
; {
.dbline 77
; //twi event
; switch (TWSR&0xF8)
in R20,0x1
clr R21
andi R20,248
andi R21,0
cpi R20,144
ldi R30,0
cpc R21,R30
brne X3
xjmp L25
X3:
ldi R24,144
ldi R25,0
cp R24,R20
cpc R25,R21
brge X4
xjmp L33
X4:
L32:
cpi R20,112
ldi R30,0
cpc R21,R30
brne X5
xjmp L23
X5:
ldi R24,112
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L35
L34:
cpi R20,96
ldi R30,0
cpc R21,R30
brne X6
xjmp L23
X6:
ldi R24,96
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L37
L36:
cpi R20,0
cpc R20,R21
brne X7
xjmp L31
X7:
X0:
xjmp L21
L37:
cpi R20,104
ldi R30,0
cpc R21,R30
brne X8
xjmp L23
X8:
xjmp L21
L35:
cpi R20,128
ldi R30,0
cpc R21,R30
brne X9
xjmp L24
X9:
ldi R24,128
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L39
L38:
cpi R20,120
ldi R30,0
cpc R21,R30
brne X10
xjmp L23
X10:
xjmp L21
L39:
cpi R20,136
ldi R30,0
cpc R21,R30
brne X11
xjmp L24
X11:
xjmp L21
L33:
cpi R20,176
ldi R30,0
cpc R21,R30
brne X12
xjmp L27
X12:
ldi R24,176
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L41
L40:
cpi R20,160
ldi R30,0
cpc R21,R30
brne X13
xjmp L26
X13:
ldi R24,160
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L43
L42:
cpi R20,152
ldi R30,0
cpc R21,R30
breq L25
xjmp L21
L43:
cpi R20,168
ldi R30,0
cpc R21,R30
brne X14
xjmp L27
X14:
xjmp L21
L41:
cpi R20,192
ldi R30,0
cpc R21,R30
brne X15
xjmp L29
X15:
ldi R24,192
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L45
L44:
cpi R20,184
ldi R30,0
cpc R21,R30
breq L28
xjmp L21
L45:
cpi R20,200
ldi R30,0
cpc R21,R30
breq L29
cpi R20,200
ldi R30,0
cpc R21,R30
brlt L21
L46:
cpi R20,248
ldi R30,0
cpc R21,R30
breq L21
xjmp L21
X1:
.dbline 78
; {
L23:
.dbline 84
; //从接收
; case TW_SR_SLA_ACK:
; case TW_SR_ARB_LOST_SLA_ACK:
; case TW_SR_GCALL_ACK:
; case TW_SR_ARB_LOST_GCALL_ACK:
; Twi_Ack(); //返回ACK
.dbline 84
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 84
.dbline 84
.dbline 85
; break;
xjmp L21
L24:
.dbline 88
; case TW_SR_DATA_ACK:
; case TW_SR_DATA_NACK:
; main_tmp = TWDR;
in R2,0x3
sts _main_tmp,R2
.dbline 89
; PORTA = ~ TWDR; //接收数据并显示
in R2,0x3
com R2
out 0x1b,R2
.dbline 90
; Twi_Ack(); //返回ACK
.dbline 90
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 90
.dbline 90
.dbline 91
; break;
xjmp L21
L25:
.dbline 94
; case TW_SR_GCALL_DATA_ACK:
; case TW_SR_GCALL_DATA_NACK:
; Twi_Ack(); //返回ACK
.dbline 94
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 94
.dbline 94
.dbline 95
; break;
xjmp L21
L26:
.dbline 97
; case TW_SR_STOP:
; Twi_Ack();
.dbline 97
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 97
.dbline 97
.dbline 98
; break;
xjmp L21
L27:
.dbline 104
; //从发送*****************************
;
; case TW_ST_SLA_ACK: // 0xA8: 自己的SLA+R 已经被接收,ACK 已返回
; case TW_ST_ARB_LOST_SLA_ACK:// 0xB0: SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收,ACK 已返回
; // 被选中为从读出 (数据将从传回主机)
; TWDR=main_tmp; //发送全局变量中值
lds R2,_main_tmp
out 0x3,R2
.dbline 105
; Twi_Ack();
.dbline 105
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 105
.dbline 105
.dbline 106
; break;
xjmp L21
L28:
.dbline 109
; case TW_ST_DATA_ACK: // 0xB8: TWDR 里数据已经发送,接收到ACK
; //发送数据位
; TWDR=main_tmp;
lds R2,_main_tmp
out 0x3,R2
.dbline 110
; break;
xjmp L21
L29:
.dbline 115
; case TW_ST_DATA_NACK: // 0xC0: TWDR 里数据已经发送接收到NOT ACK
; case TW_ST_LAST_DATA: // 0xC8: TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK
; // 全部完成
; // 从方式开放
; Twi_NoAcK();
.dbline 115
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
.dbline 115
.dbline 115
.dbline 116
; twi_slave_init(0x50); //重新回到初始化状态,等待接收模式的到来
ldi R16,80
xcall _twi_slave_init
.dbline 117
; break;
xjmp L21
X2:
.dbline 120
; case TW_NO_INFO: // 0xF8: 没有相关的状态信息;TWINT = “0”
; // 无操作
; break;
L31:
.dbline 123
in R24,0x36
andi R24,15
ori R24,208
out 0x36,R24
.dbline 124
.dbline 126
L21:
.dbline -2
L19:
xcall pop_gset1
xcall pop_lset
.dbline 0 ; func end
reti
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -