📄 twi.s
字号:
.module TWI.C
.area data(ram, con, rel)
_table::
.blkb 2
.area idata
.byte 1,2
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 4,8
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 16,32
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 64,128
.area data(ram, con, rel)
.dbfile E:\PQ-1A\我的AVR\zlg7290\TWI.C
.dbsym e table _table A[8:8]c
_table1::
.blkb 2
.area idata
.byte 0,0
.area data(ram, con, rel)
.dbfile E:\PQ-1A\我的AVR\zlg7290\TWI.C
.blkb 2
.area idata
.byte 0,0
.area data(ram, con, rel)
.dbfile E:\PQ-1A\我的AVR\zlg7290\TWI.C
.blkb 2
.area idata
.byte 0,0
.area data(ram, con, rel)
.dbfile E:\PQ-1A\我的AVR\zlg7290\TWI.C
.blkb 2
.area idata
.byte 0,0
.area data(ram, con, rel)
.dbfile E:\PQ-1A\我的AVR\zlg7290\TWI.C
.dbsym e table1 _table1 A[8:8]c
.area text(rom, con, rel)
.dbfile E:\PQ-1A\我的AVR\zlg7290\TWI.C
.dbfunc e delay _delay fV
; x -> R20,R21
; y -> R22,R23
; z -> R16,R17
.even
_delay::
xcall push_gset2
.dbline -1
.dbline 15
; #include <iom128v.h>
; #include <iom128.h>
; #include <macros.h>
; #include "TWI.h"
;
; #define uchar unsigned char
; #define uint unsigned int
; #define Page_size 8
; #define Page_mask Page_size-1
; //#pragma data:code
; //const
; char table[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
; char table1[8]={0,0,0,0,0,0,0,0};
; void delay(uint z)
; {
.dbline 17
; uint x,y;
; for(x=z;x>0;x--)
movw R20,R16
xjmp L5
L2:
.dbline 18
ldi R22,1100
ldi R23,4
xjmp L9
L6:
.dbline 18
L7:
.dbline 18
subi R22,1
sbci R23,0
L9:
.dbline 18
cpi R22,0
cpc R22,R23
brne L6
X0:
L3:
.dbline 17
subi R20,1
sbci R21,0
L5:
.dbline 17
cpi R20,0
cpc R20,R21
brne L2
X1:
.dbline -2
.dbline 19
; for(y=1100;y>0;y--);
; }
L1:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r x 20 i
.dbsym r y 22 i
.dbsym r z 16 i
.dbend
.dbfunc e TWI_init _TWI_init fV
.even
_TWI_init::
.dbline -1
.dbline 28
;
;
; /*
; 函数:TWI_init()
; 功能:I2C总线初始化,使总线处于空闲状态
; 说明:在main()函数的开始处,通常应当要执行一次本函数
; */
; void TWI_init()
; {
.dbline 29
; TWBR=0X22;
ldi R24,34
sts 112,R24
.dbline 30
; TWSR=0;
clr R2
sts 113,R2
.dbline 31
; TWCR=0X44;
ldi R24,68
sts 116,R24
.dbline -2
.dbline 32
; }
L10:
.dbline 0 ; func end
ret
.dbend
.dbfunc e TWI_start _TWI_start fc
.even
_TWI_start::
.dbline -1
.dbline 42
;
; /*
; 函数:TWI_start()
; 功能:产生I2C总线的起始状态
; 说明:
; 本函数也可以用来产生重复起始状态
; 本函数执行后,I2C总线处于忙状态
; */
; uchar TWI_start(void)
; {
.dbline 43
; TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
ldi R24,164
sts 116,R24
L12:
.dbline 44
L13:
.dbline 44
; while(!(TWCR&(1<<TWINT)));
lds R2,116
sbrs R2,7
rjmp L12
.dbline 45
; return 1;
ldi R16,1
.dbline -2
L11:
.dbline 0 ; func end
ret
.dbend
.dbfunc e TWI_stop _TWI_stop fV
.even
_TWI_stop::
.dbline -1
.dbline 49
; }
;
; void TWI_stop(void)
; {
.dbline 50
; TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
ldi R24,148
sts 116,R24
.dbline -2
.dbline 51
; }
L15:
.dbline 0 ; func end
ret
.dbend
.dbfunc e TWI_writeB _TWI_writeB fc
; ack -> R20
; c -> R16
.even
_TWI_writeB::
xcall push_gset1
.dbline -1
.dbline 63
;
; /*
; 函数:TWI_writeB()
; 功能:向I2C总线写1个字节的数据
; 返回:
; 0: 从机无应答
; 1:从机应答
; 参数:
; c:要写到总线上的数据
; */
; uchar TWI_writeB(uchar c)
; {
.dbline 64
; uchar ack=1;
ldi R20,1
.dbline 65
; TWDR=c;
sts 115,R16
.dbline 66
; TWCR=(1<<TWINT)|(1<<TWEN);
ldi R24,132
sts 116,R24
L17:
.dbline 67
L18:
.dbline 67
; while(!(TWCR&(1<<TWINT)));
lds R2,116
sbrs R2,7
rjmp L17
.dbline 68
; if((TWSR&0xF8)!=SLA_W_ACK)
lds R24,113
andi R24,248
cpi R24,24
breq L20
.dbline 69
; ack=0;
clr R20
L20:
.dbline 70
; return ack;
mov R16,R20
.dbline -2
L16:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r ack 20 c
.dbsym r c 16 c
.dbend
.dbfunc e TWI_readB _TWI_readB fc
; ack -> R16
.even
_TWI_readB::
.dbline -1
.dbline 81
; }
;
; /*
; 函数:TWI_readB()
; 功能:从从机读取1个字节的数据
; 返回:读取的一个字节数据
; 说明:ack=0; 不应答
; ack=1; 应答
; */
; uchar TWI_readB(uchar ack)
; {
.dbline 82
; if(ack)
tst R16
breq L23
.dbline 83
; TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);
ldi R24,196
sts 116,R24
xjmp L26
L23:
.dbline 85
; else
; TWCR=(1<<TWINT)|(1<<TWEN);
ldi R24,132
sts 116,R24
L25:
.dbline 86
L26:
.dbline 86
; while(!(TWCR&(1<<TWINT)));
lds R2,116
sbrs R2,7
rjmp L25
.dbline 87
; return(TWDR);
lds R16,115
.dbline -2
L22:
.dbline 0 ; func end
ret
.dbsym r ack 16 c
.dbend
.dbfunc e TWI_page_write _TWI_page_write fc
; i -> R20
; arr -> R22,R23
; n -> R10
; addr -> R20
; devadd -> R12
.even
_TWI_page_write::
xcall push_gset4
mov R20,R18
mov R12,R16
ldd R10,y+8
ldd R22,y+10
ldd R23,y+11
.dbline -1
.dbline 106
; }
;
; /*
; 函数:TWI_page_write()
; 功能:I2C总线综合发送函数,向从机发送多个字节的数据,整页发送
; 参数:
; SlaveAddr:从机地址(7位纯地址,不含读写位)
; addr:从机的子地址
; *arr:要发送的数据
; n:数据的字节数
; 返回:
; 1:发送成功
; 0:在发送过程中出现异常
; 说明:
; 本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址
; 当从机没有子地址时,参数addr任意
; */
; uchar TWI_page_write(uchar devadd,uchar addr,uchar n,uchar *arr)//
; {
.dbline 108
; uchar i;
; TWI_start();
xcall _TWI_start
.dbline 109
; TWI_writeB(devadd);
mov R16,R12
xcall _TWI_writeB
.dbline 110
; TWI_writeB(addr);
mov R16,R20
xcall _TWI_writeB
.dbline 111
; for(i=1;i<=n;i++)
ldi R20,1
xjmp L32
L29:
.dbline 112
.dbline 115
movw R30,R22
ldd R16,z+0
xcall _TWI_writeB
.dbline 116
subi R22,255 ; offset = 1
sbci R23,255
.dbline 117
L30:
.dbline 111
inc R20
L32:
.dbline 111
cp R10,R20
brsh L29
.dbline 118
; {
; //TWI_writeB(i);
; //table[i]=i;
; TWI_writeB(*arr);
; arr++;
; }
; TWI_stop();
xcall _TWI_stop
.dbline 119
; delay(80);
ldi R16,80
ldi R17,0
xcall _delay
.dbline -2
.dbline 120
; }
L28:
xcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r arr 22 pc
.dbsym r n 10 c
.dbsym r addr 20 c
.dbsym r devadd 12 c
.dbend
.dbfunc e TWI_write _TWI_write fc
; n_tmp -> R14
; arr -> R20,R21
; n -> R22
; addr -> R10
; devadd -> R12
.even
_TWI_write::
xcall push_gset5
mov R10,R18
mov R12,R16
sbiw R28,4
ldd R22,y+14
ldd R20,y+16
ldd R21,y+17
.dbline -1
.dbline 138
;
; /*
; 函数:TWI_page_write()
; 功能:I2C总线综合发送函数,向从机发送多个字节的数据
; 参数:
; SlaveAddr:从机地址(7位纯地址,不含读写位)
; addr:从机的子地址
; *arr:要发送的数据
; n:数据的字节数
; 返回:
; 1:发送成功
; 0:在发送过程中出现异常
; 说明:
; 本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址
; 当从机没有子地址时,参数addr任意
; */
; uchar TWI_write(uchar devadd,uchar addr,uchar n,uchar *arr)//
; {
.dbline 140
; uchar n_tmp;
; n_tmp=Page_size-(uchar)(addr&Page_mask);
mov R24,R10
clr R25
andi R24,7
andi R25,0
ldi R25,8
mov R14,R25
sub R14,R24
.dbline 141
; if((n>n_tmp)&&(n_tmp!=0))
cp R14,R22
brsh L37
tst R14
breq L37
.dbline 142
; {
.dbline 143
; TWI_page_write(devadd,addr,n_tmp,arr);//
std y+2,R20
std y+3,R21
std y+0,R14
mov R18,R10
mov R16,R12
xcall _TWI_page_write
.dbline 144
; addr+=n_tmp;
add R10,R14
.dbline 145
; n-=n_tmp;
sub R22,R14
.dbline 146
; arr+=n_tmp;
mov R2,R14
clr R3
add R20,R2
adc R21,R3
.dbline 147
; }
xjmp L37
L36:
.dbline 149
.dbline 150
std y+2,R20
std y+3,R21
ldi R24,8
std y+0,R24
mov R18,R10
mov R16,R12
xcall _TWI_page_write
.dbline 151
mov R24,R10
subi R24,248 ; addi 8
mov R10,R24
.dbline 152
subi R22,8
.dbline 153
subi R20,248 ; offset = 8
sbci R21,255
.dbline 154
L37:
.dbline 148
cpi R22,8
brsh L36
.dbline 155
tst R22
breq L39
.dbline 156
std y+2,R20
std y+3,R21
std y+0,R22
mov R18,R10
mov R16,R12
xcall _TWI_page_write
L39:
.dbline -2
.dbline 157
; while(n>=Page_size)
; {
; TWI_page_write(devadd,addr,Page_size,arr);//
; addr+=Page_size;
; n-=Page_size;
; arr+=Page_size;
; }
; if(n!=0)
; TWI_page_write(devadd,addr,n,arr);//
; }
L33:
adiw R28,4
xcall pop_gset5
.dbline 0 ; func end
ret
.dbsym r n_tmp 14 c
.dbsym r arr 20 pc
.dbsym r n 22 c
.dbsym r addr 10 c
.dbsym r devadd 12 c
.dbend
.dbfunc e TWI_read _TWI_read fc
; i -> R20
; arr -> R22,R23
; n -> R10
; addr -> R12
; devadd -> R20
.even
_TWI_read::
xcall push_gset4
mov R12,R18
mov R20,R16
ldd R10,y+8
ldd R22,y+10
ldd R23,y+11
.dbline -1
.dbline 175
;
; /*
; 函数:TWI_read()
; 功能:I2C总线综合接收函数,从从机接收多个字节的数据
; 参数:
; SlaveAddr:从机地址(7位纯地址,不含读写位)
; addr:从机的子地址
; *arr:要发送的数据
; n:数据的字节数
; 返回:
; 1:接收成功
; 0:在接收过程中出现异常
; 说明:
; 本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址
; 当从机没有子地址时,参数addr任意
; */
; uchar TWI_read(uchar devadd,uchar addr,uchar n,uchar *arr)
; {
.dbline 177
; uchar i;
; TWI_start();
xcall _TWI_start
.dbline 178
; TWI_writeB(devadd);
mov R16,R20
xcall _TWI_writeB
.dbline 179
; TWI_writeB(addr);
mov R16,R12
xcall _TWI_writeB
.dbline 180
; TWI_start();
xcall _TWI_start
.dbline 181
; TWI_writeB(devadd|1);
mov R16,R20
ori R16,1
xcall _TWI_writeB
.dbline 182
; for(i=1;i<=n-1;i++)
ldi R20,1
xjmp L45
L42:
.dbline 183
.dbline 184
ldi R16,1
xcall _TWI_readB
movw R30,R22
std z+0,R16
.dbline 185
subi R22,255 ; offset = 1
sbci R23,255
.dbline 186
L43:
.dbline 182
inc R20
L45:
.dbline 182
mov R24,R10
subi R24,1
cp R24,R20
brsh L42
.dbline 187
; {
; *arr= TWI_readB(1);
; arr++;
; }
; *arr= TWI_readB(0);
clr R16
xcall _TWI_readB
movw R30,R22
std z+0,R16
.dbline 188
; TWI_stop();
xcall _TWI_stop
.dbline -2
.dbline 189
; }
L41:
xcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r arr 22 pc
.dbsym r n 10 c
.dbsym r addr 12 c
.dbsym r devadd 20 c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -