📄 twi.s
字号:
.module twi.c
.area text(rom, con, rel)
.dbfile F:\2007电子设计\古欣\twitest\twi_test\twi.c
.dbfunc e twi_master_init _twi_master_init fV
.even
_twi_master_init::
.dbline -1
.dbline 7
;
; #include "config.h"
;
; //TWI master initialize
; // bit rate:100
; void twi_master_init(void)
; {
.dbline 8
; TWCR= 0x00; //disable twi
clr R2
out 0x36,R2
.dbline 9
; TWBR= 0x64; //set bit rate
ldi R24,100
out 0x0,R24
.dbline 10
; TWSR= 0x00; //set prescale
out 0x1,R2
.dbline 11
; TWAR= 0x00; //set slave address
out 0x2,R2
.dbline 12
; 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 18
; }
;
; //TWI slave initialize
; // bit rate:100
; void twi_slave_init(uint8 add)
; {
.dbline 19
; TWCR= 0x00; //disable twi
clr R2
out 0x36,R2
.dbline 20
; TWBR= 0x64; //set bit rate
ldi R24,100
out 0x0,R24
.dbline 21
; TWSR= 0x00; //set prescale
out 0x1,R2
.dbline 22
; TWAR= (add<<1); //set slave address 从机地址为 0x01
mov R2,R16
lsl R2
out 0x2,R2
.dbline 23
; 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 29
; //TWEN必须置位以使能TWI接口。TWEA也要置位以使主机寻址到自己(从机地址或广播) 时返回确认信息ACK
; }
;
; //总线上起动开始条件
; void i2c_start(void)
; {
.dbline 30
; TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
ldi R24,164
out 0x36,R24
L4:
.dbline 31
L5:
.dbline 31
; 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_addr _i2c_write_addr fc
; r_w -> R18
; addr -> R16
.even
_i2c_write_addr::
.dbline -1
.dbline 37
; }
;
; //把一个字节数据输入器件, 返回TWI状态
; //发送地址,r_w:1为读,0为写
; uint8 i2c_write_addr(uint8 addr,uint8 r_w)
; {
.dbline 38
; if(r_w)
tst R18
breq L8
.dbline 39
; {
.dbline 40
; TWDR = addr|r_w; //RW 为1:读操作
mov R2,R16
or R2,R18
out 0x3,R2
.dbline 41
; }
xjmp L9
L8:
.dbline 43
; else
; {
.dbline 44
; TWDR = addr & 0xFE; // RW 为0: 写操作
mov R24,R16
andi R24,254
out 0x3,R24
.dbline 45
; }
L9:
.dbline 47
;
; TWCR = (1<<TWINT)|(1<<TWEN);
ldi R24,132
out 0x36,R24
L10:
.dbline 48
L11:
.dbline 48
; while (!(TWCR & (1<<TWINT)));
in R2,0x36
sbrs R2,7
rjmp L10
.dbline 49
; _NOP();
nop
.dbline 50
; return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
in R16,0x1
andi R16,248
.dbline -2
L7:
.dbline 0 ; func end
ret
.dbsym r r_w 18 c
.dbsym r addr 16 c
.dbend
.dbfunc e i2c_write_data _i2c_write_data fc
; data -> R16
.even
_i2c_write_data::
.dbline -1
.dbline 56
; }
;
; //把一个字节数据输入器件, 返回TWI状态
; //发送数据
; uint8 i2c_write_data(uint8 data)
; {
.dbline 57
; TWDR = data;
out 0x3,R16
.dbline 58
; TWCR = (1<<TWINT)|(1<<TWEN);
ldi R24,132
out 0x36,R24
L14:
.dbline 59
L15:
.dbline 59
; while (!(TWCR & (1<<TWINT)));
in R2,0x36
sbrs R2,7
rjmp L14
.dbline 60
; _NOP();
nop
.dbline 61
; return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
in R16,0x1
andi R16,248
.dbline -2
L13:
.dbline 0 ; func end
ret
.dbsym r data 16 c
.dbend
.dbfunc e i2c_read _i2c_read fc
.even
_i2c_read::
.dbline -1
.dbline 67
; }
;
;
; //从器件读出一个字节
; uint8 i2c_read(void)
; {
.dbline 68
; TWCR = (1<<TWINT)|(1<<TWEN);
ldi R24,132
out 0x36,R24
.dbline 69
; Twi_NoAcK();
.dbline 69
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
.dbline 69
.dbline 69
L18:
.dbline 70
L19:
.dbline 70
; while (!(TWCR & (1<<TWINT)));
in R2,0x36
sbrs R2,7
rjmp L18
.dbline 71
; return(TWDR);
in R16,0x3
.dbline -2
L17:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2c_stop _i2c_stop fV
.even
_i2c_stop::
.dbline -1
.dbline 76
; }
;
; //总线上起动停止条件
; void i2c_stop(void)
; {
.dbline 77
; TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
ldi R24,148
out 0x36,R24
.dbline -2
L21:
.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 82
; }
;
; //操作步骤: 启动,发送地址,发送数据,关闭总线
; void i2c_maste_transt(uint8 addr, uint8 data)
; {
.dbline 83
; i2c_start();
xcall _i2c_start
.dbline 85
;
; if(i2c_write_addr(addr, 0)==TW_MT_SLA_ACK) //发送地址成功并收到ACK
clr R18
mov R16,R22
xcall _i2c_write_addr
cpi R16,24
brne L23
.dbline 86
; {
.dbline 87
; i2c_write_data(data);
mov R16,R20
xcall _i2c_write_data
.dbline 88
; }
L23:
.dbline 89
; i2c_stop();
xcall _i2c_stop
.dbline -2
L22:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r data 20 c
.dbsym r addr 22 c
.dbend
.dbfunc e i2c_maste_read _i2c_maste_read fc
; tmp -> R20
; addr -> R22
.even
_i2c_maste_read::
xcall push_gset2
mov R22,R16
.dbline -1
.dbline 93
; }
; //操作步骤,启动,发送地址,读数据,关闭总线
; uint8 i2c_maste_read(uint8 addr)
; {
.dbline 94
; uint8 tmp=0;
clr R20
.dbline 95
; i2c_start();
xcall _i2c_start
.dbline 96
; if(i2c_write_addr(addr, 1)==TW_MR_SLA_ACK) //发送地址成功并收到ACK
ldi R18,1
mov R16,R22
xcall _i2c_write_addr
cpi R16,64
brne L26
.dbline 97
; {
.dbline 98
; tmp=i2c_read();
xcall _i2c_read
mov R20,R16
.dbline 99
; }
L26:
.dbline 100
; i2c_stop();
xcall _i2c_stop
.dbline 101
; return tmp;
mov R16,R20
.dbline -2
L25:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r tmp 20 c
.dbsym r addr 22 c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -