📄 twi.s
字号:
.module twi.c
.area text(rom, con, rel)
.dbfile E:\ICCAVR\project\AVRMEG~2\icc\013-IIC-LED\twi.c
.dbfunc e error _error fV
; type -> R16
.even
_error::
xcall push_gset1
.dbline -1
.dbline 18
; /*
; I2C总线/TWI操作模块
; 1、读取和写入函数
; 2、地址有效范围255
; 3、数据长度为单字节
; 4、函数采用查询方式
; 5、可直接嵌入到项目中使用
; 6、晶振频率:1M
; 7、总线速度:50K
;
; AVR_AFA
; www.iccavr.com
; */
;
; #include "iom16v.h"
;
; /*I2C总线主机模式错误处理*/
; void error(unsigned char type) {
.dbline 20
;
; switch (type & 0xF8) {
mov R20,R16
clr R21
andi R20,248
andi R21,0
cpi R20,48
ldi R30,0
cpc R21,R30
breq L6
ldi R24,48
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L10
L9:
cpi R20,32
ldi R30,0
cpc R21,R30
breq L5
xjmp L2
L10:
cpi R20,56
ldi R30,0
cpc R21,R30
breq L3
cpi R20,56
ldi R30,0
cpc R21,R30
brlt L2
L11:
cpi R20,72
ldi R30,0
cpc R21,R30
breq L8
xjmp L2
X0:
.dbline 20
L5:
.dbline 23
; case 0x20: /*址址写失败*/
; /*stop 停止*/
; TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
ldi R24,148
out 0x36,R24
.dbline 24
; break;
xjmp L3
L6:
.dbline 27
; case 0x30: /*数据写失败*/
; /*stop 停止*/
; TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
ldi R24,148
out 0x36,R24
.dbline 28
; break;
xjmp L3
X1:
.dbline 30
; case 0x38: /*仲裁失败*/
; break;
L8:
.dbline 33
; case 0x48: /*址址读失败*/
; /*stop 停止*/
; TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
ldi R24,148
out 0x36,R24
.dbline 34
; break;
L2:
L3:
.dbline -2
L1:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r type 16 c
.dbend
.dbfunc e twi_write _twi_write fc
; dd -> R20
; addr -> R22
.even
_twi_write::
xcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 39
; }
; }
;
; /*I2C总线单字节写入*/
; unsigned char twi_write(unsigned char addr, unsigned char dd) {
.dbline 41
;
; TWBR = 2;
ldi R24,2
out 0x0,R24
.dbline 44
;
; /*start 启动*/
; TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
ldi R24,164
out 0x36,R24
L13:
.dbline 45
L14:
.dbline 45
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L13
.dbline 46
; if ((TWSR & 0xF8) != 0x08) {
in R24,0x1
andi R24,248
cpi R24,8
breq L16
.dbline 46
.dbline 47
; error(TWSR);
in R16,0x1
xcall _error
.dbline 48
; return 0;
clr R16
xjmp L12
L16:
.dbline 52
; }
;
; /*SLA_W 芯片地址*/
; TWDR = 0xA0;
ldi R24,160
out 0x3,R24
.dbline 53
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L18:
.dbline 54
L19:
.dbline 54
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L18
.dbline 55
; if ((TWSR & 0xF8) != 0x18) {
in R24,0x1
andi R24,248
cpi R24,24
breq L21
.dbline 55
.dbline 56
; error(TWSR);
in R16,0x1
xcall _error
.dbline 57
; return 0;
clr R16
xjmp L12
L21:
.dbline 61
; }
;
; /*addr 操作地址*/
; TWDR = addr;
out 0x3,R22
.dbline 62
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L23:
.dbline 63
L24:
.dbline 63
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L23
.dbline 64
; if ((TWSR & 0xF8) != 0x28) {
in R24,0x1
andi R24,248
cpi R24,40
breq L26
.dbline 64
.dbline 65
; error(TWSR);
in R16,0x1
xcall _error
.dbline 66
; return 0;
clr R16
xjmp L12
L26:
.dbline 70
; }
;
; /*dd 写入数据*/
; TWDR = dd;
out 0x3,R20
.dbline 71
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L28:
.dbline 72
L29:
.dbline 72
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L28
.dbline 73
; if ((TWSR & 0xF8) != 0x28) {
in R24,0x1
andi R24,248
cpi R24,40
breq L31
.dbline 73
.dbline 74
; error(TWSR);
in R16,0x1
xcall _error
.dbline 75
; return 0;
clr R16
xjmp L12
L31:
.dbline 79
; }
;
; /*stop 停止*/
; TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
ldi R24,148
out 0x36,R24
.dbline 80
; return 1;
ldi R16,1
.dbline -2
L12:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r dd 20 c
.dbsym r addr 22 c
.dbend
.dbfunc e twi_read _twi_read fc
; dd -> R20,R21
; addr -> R22
.even
_twi_read::
xcall push_gset2
movw R20,R18
mov R22,R16
.dbline -1
.dbline 84
; }
;
; /*I2C总线单字节读取*/
; unsigned char twi_read(unsigned char addr, unsigned char *dd) {
.dbline 86
;
; TWBR = 2;
ldi R24,2
out 0x0,R24
.dbline 89
;
; /*start 启动*/
; TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
ldi R24,164
out 0x36,R24
L34:
.dbline 90
L35:
.dbline 90
; while(!(TWCR&(1<<TWINT)));
in R2,0x36
sbrs R2,7
rjmp L34
.dbline 91
; if ((TWSR & 0xF8) != 0x08) {
in R24,0x1
andi R24,248
cpi R24,8
breq L37
.dbline 91
.dbline 92
; error(TWSR);
in R16,0x1
xcall _error
.dbline 93
; return 0;
clr R16
xjmp L33
L37:
.dbline 97
; }
;
; /*SLA_W 芯片地址*/
; TWDR = 0xA0;
ldi R24,160
out 0x3,R24
.dbline 98
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L39:
.dbline 99
L40:
.dbline 99
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L39
.dbline 100
; if ((TWSR & 0xF8) != 0x18) {
in R24,0x1
andi R24,248
cpi R24,24
breq L42
.dbline 100
.dbline 101
; error(TWSR);
in R16,0x1
xcall _error
.dbline 102
; return 0;
clr R16
xjmp L33
L42:
.dbline 106
; }
;
; /*addr 操作地址*/
; TWDR = addr;
out 0x3,R22
.dbline 107
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L44:
.dbline 108
L45:
.dbline 108
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L44
.dbline 109
; if ((TWSR & 0xF8) != 0x28) {
in R24,0x1
andi R24,248
cpi R24,40
breq L47
.dbline 109
.dbline 110
; error(TWSR);
in R16,0x1
xcall _error
.dbline 111
; return 0;
clr R16
xjmp L33
L47:
.dbline 115
; }
;
; /*start 启动*/
; TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
ldi R24,164
out 0x36,R24
L49:
.dbline 116
L50:
.dbline 116
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L49
.dbline 117
; if ((TWSR & 0xF8) != 0x10) {
in R24,0x1
andi R24,248
cpi R24,16
breq L52
.dbline 117
.dbline 118
; error(TWSR);
in R16,0x1
xcall _error
.dbline 119
; return 0;
clr R16
xjmp L33
L52:
.dbline 123
; }
;
; /*SLA_R 芯片地址*/
; TWDR = 0xA1;
ldi R24,161
out 0x3,R24
.dbline 124
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L54:
.dbline 125
L55:
.dbline 125
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L54
.dbline 126
; if ((TWSR & 0xF8) != 0x40) {
in R24,0x1
andi R24,248
cpi R24,64
breq L57
.dbline 126
.dbline 127
; error(TWSR);
in R16,0x1
xcall _error
.dbline 128
; return 0;
clr R16
xjmp L33
L57:
.dbline 132
; }
;
; /*读取数据*/
; TWCR = (1 << TWINT) | (1 << TWEN);
ldi R24,132
out 0x36,R24
L59:
.dbline 133
L60:
.dbline 133
; while (!(TWCR & (1 << TWINT)));
in R2,0x36
sbrs R2,7
rjmp L59
.dbline 134
; if ((TWSR & 0xF8) != 0x58) {
in R24,0x1
andi R24,248
cpi R24,88
breq L62
.dbline 134
.dbline 135
; error(TWSR);
in R16,0x1
xcall _error
.dbline 136
; return 0;
clr R16
xjmp L33
L62:
.dbline 138
; }
; *dd = TWDR;
in R2,0x3
movw R30,R20
std z+0,R2
.dbline 141
;
; /*stop 停止*/
; TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
ldi R24,148
out 0x36,R24
.dbline 142
; return 1;
ldi R16,1
.dbline -2
L33:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r dd 20 pc
.dbsym r addr 22 c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -