📄 twi_1.s
字号:
.module twi_1.c
.area data(ram, con, rel)
_localBuffer::
.blkb 3
.area idata
.byte 33,33,0
.area data(ram, con, rel)
.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827\twi_1.c
.dbsym e localBuffer _localBuffer A[3:3]c
_localBufferLength::
.blkb 1
.area idata
.byte 32
.area data(ram, con, rel)
.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827\twi_1.c
.dbsym e localBufferLength _localBufferLength c
_EnFlex::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827\twi_1.c
.dbsym e EnFlex _EnFlex c
_I2cNotAck::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827\twi_1.c
.dbsym e I2cNotAck _I2cNotAck c
.area text(rom, con, rel)
.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827\twi_1.c
.dbfunc e i2cSetBitrate _i2cSetBitrate fV
; bitrate_div -> R10
; bitrateKHz -> R10,R11
.even
_i2cSetBitrate::
xcall push_gset3
movw R10,R16
.dbline -1
.dbline 46
; /************************************************************************/
; //I2C文件读写库函数V1.1
; /* I2C读写程序,使用前要确保
; 1.中断向量号的正确
; 2.确保TWI的初始化
; 3.此版本文件是从twi.c派生出来的,读写缓存都不再单独分配,而是由应用函数和场合指定
; 4.此版本是速度优先版本,特点是速度快,但读写都是在编译时确定的,不是用指针方式寻址
; 5.没有通信超时退出
; */
; /************************************************************************/
;
; #include "twi.h"
;
;
; // I2C标准波特率:
; // 低速 100KHz
; // 高速 400KHz
;
; // I2C 状态和地址变量
; static volatile eI2cStateType I2cState;
; static unsigned char I2cDeviceAddrRW;
; // 发送缓冲区
; //static unsigned char I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
; unsigned char *I2cSendData;
; static unsigned int I2cSendDataIndex;
; static unsigned int I2cSendDataLength;
; // 接收缓冲区
; //static unsigned char I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
; unsigned char *I2cReceiveData;
; static unsigned int I2cReceiveDataIndex;
; static unsigned int I2cReceiveDataLength;
;
; unsigned char I2cComStatus; //通信状态变量
;
; unsigned char localBuffer[] = "!!";
; unsigned char localBufferLength = 0x20;
;
; // 存放发送长度的地址
; unsigned int* SlaveSendLength;
;
; unsigned char EnFlex = 0; /*变长接收使能*/
;
; unsigned char I2cNotAck = 0; /*如果在主机发送或接收时,SLA+R或者SLA+W,ACK未收到,则I2cNotAck=0xff,否则为0*/
; //设置总线速率
; void i2cSetBitrate(unsigned int bitrateKHz)
; {
.dbline 53
; unsigned char bitrate_div;
; // SCL freq = F_CPU/(16+2*TWBR))
; #ifdef TWPS0
; // 对于用速率分频的AVR (mega128)
; // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
; // set TWPS to zero
; TWSR&=~(1<<TWPS0);
cbi 0x1,0
.dbline 54
; TWSR&=~(1<<TWPS1);
cbi 0x1,1
.dbline 57
; #endif
; // 计算分频
; bitrate_div = ((F_CPU/1000l)/bitrateKHz);
movw R2,R10
clr R4
clr R5
ldi R20,64
ldi R21,31
ldi R22,0
ldi R23,0
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R20
movw R18,R22
xcall div32s
mov R10,R16
.dbline 58
; if(bitrate_div >= 16)
mov R24,R10
cpi R16,16
brlo L3
.dbline 59
; bitrate_div = (bitrate_div-16)/2;
subi R24,16
mov R10,R24
lsr R10
L3:
.dbline 60
; TWBR = bitrate_div;
out 0x0,R10
.dbline -2
L2:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r bitrate_div 10 c
.dbsym r bitrateKHz 10 i
.dbend
.dbfunc e i2cInit _i2cInit fV
.even
_i2cInit::
.dbline -1
.dbline 65
; }
;
; //总线初始化
; void i2cInit(void)
; {
.dbline 68
;
; // I2C总线使能
; TWCR|=1<<TWEN;
in R24,0x36
ori R24,4
out 0x36,R24
.dbline 70
; // 状态设置
; I2cState = I2C_IDLE;
clr R2
sts _I2cState,R2
.dbline 72
; // 开I2C中断和回应
; TWCR|=1<<TWIE;
in R24,0x36
ori R24,1
out 0x36,R24
.dbline 73
; TWCR|=1<<TWEA;
in R24,0x36
ori R24,64
out 0x36,R24
.dbline -2
L5:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2cSetLocalDeviceAddr _i2cSetLocalDeviceAddr fV
; genCallEn -> R18
; deviceAddr -> R16
.even
_i2cSetLocalDeviceAddr::
xcall push_gset1
.dbline -1
.dbline 82
; }
;
; /************************************************************************/
; /* 设置本机从地址及是否响应广播
; [in]:uchar deviceAddr,设备地址
; [in]:uchar genCallEn,广播使能!0-使能,0-不使能 */
; /************************************************************************/
; void i2cSetLocalDeviceAddr(unsigned char deviceAddr, unsigned char genCallEn)
; {
.dbline 84
; // 设置本机从地址 (从方式时)
; TWAR=(deviceAddr&0xFE)|(genCallEn?1:0);
tst R18
breq L7
ldi R20,1
ldi R21,0
xjmp L8
L7:
clr R20
clr R21
L8:
mov R24,R16
clr R25
andi R24,254
andi R25,0
or R24,R20
or R25,R21
out 0x2,R24
.dbline -2
L6:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r genCallEn 18 c
.dbsym r deviceAddr 16 c
.dbend
.dbfunc e i2cSendStart _i2cSendStart fV
.even
_i2cSendStart::
.dbline -1
.dbline 88
; }
;
; void i2cSendStart(void)
; {
.dbline 90
;
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWSTA);
in R24,0x36
andi R24,15
ori R24,160
out 0x36,R24
.dbline -2
L9:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2cSendStop _i2cSendStop fV
.even
_i2cSendStop::
.dbline -1
.dbline 94
; }
;
; void i2cSendStop(void)
; {
.dbline 96
; // 发送停止条件,保持TWEA以便从接收
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO);
in R24,0x36
andi R24,15
ori R24,208
out 0x36,R24
.dbline -2
L10:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2cWaitForComplete _i2cWaitForComplete fV
.even
_i2cWaitForComplete::
.dbline -1
.dbline 100
; }
;
; void i2cWaitForComplete(void)
; {
L12:
.dbline 102
L13:
.dbline 102
; // 等待i2c 总线操作完成
; while( !(TWCR&(1<<TWINT)) );
in R2,0x36
sbrs R2,7
rjmp L12
.dbline -2
L11:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2cSendByte _i2cSendByte fV
; data -> R16
.even
_i2cSendByte::
.dbline -1
.dbline 106
; }
;
; void i2cSendByte(unsigned char data)
; {
.dbline 108
; // 装载数据到 TWDR
; TWDR=data;
out 0x3,R16
.dbline 110
; // 发送开始
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT);
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
.dbline -2
L15:
.dbline 0 ; func end
ret
.dbsym r data 16 c
.dbend
.dbfunc e i2cReceiveByte _i2cReceiveByte fV
; ackFlag -> R16
.even
_i2cReceiveByte::
.dbline -1
.dbline 114
; }
;
; void i2cReceiveByte(unsigned char ackFlag)
; {
.dbline 116
; //开始通过 i2c 接收
; if( ackFlag )
tst R16
breq L17
.dbline 117
; {
.dbline 119
; // ackFlag = TRUE: 数据接收后回应ACK
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
.dbline 120
; }
xjmp L18
L17:
.dbline 122
.dbline 124
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
.dbline 125
L18:
.dbline -2
L16:
.dbline 0 ; func end
ret
.dbsym r ackFlag 16 c
.dbend
.dbfunc e i2cGetReceivedByte _i2cGetReceivedByte fc
.even
_i2cGetReceivedByte::
.dbline -1
.dbline 129
; else
; {
; // ackFlag = FALSE: 数据接收后无回应
; TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT);
; }
; }
;
; unsigned char i2cGetReceivedByte(void)
; {
.dbline 131
; // 返回接收到的数据
; return( TWDR );
in R16,0x3
.dbline -2
L19:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2cGetStatus _i2cGetStatus fc
.even
_i2cGetStatus::
.dbline -1
.dbline 135
; }
;
; unsigned char i2cGetStatus(void)
; {
.dbline 137
; // 返回总线状态
; return(TWSR);
in R16,0x1
.dbline -2
L20:
.dbline 0 ; func end
ret
.dbend
.dbfunc e i2cMasterSend _i2cMasterSend fc
; i -> <dead>
; length -> R20,R21
; deviceAddr -> R22
.even
_i2cMasterSend::
xcall push_gset2
movw R20,R18
mov R22,R16
.dbline -1
.dbline 141
; }
;
; unsigned char i2cMasterSend(unsigned char deviceAddr, unsigned int length)
; {
L22:
.dbline 144
L23:
.dbline 144
; unsigned char i;
; // 等待总线准备完成
; while(I2cState);
lds R2,_I2cState
tst R2
brne L22
.dbline 146
; // 设置状态
; I2cState = I2C_MASTER_TX;
ldi R24,2
sts _I2cState,R24
.dbline 148
; // 准备数据
; I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW 为0: 写操作
mov R24,R22
andi R24,254
sts _I2cDeviceAddrRW,R24
.dbline 149
; I2cSendDataIndex = 0;
clr R2
clr R3
sts _I2cSendDataIndex+1,R3
sts _I2cSendDataIndex,R2
.dbline 150
; I2cSendDataLength = length;
sts _I2cSendDataLength+1,R21
sts _I2cSendDataLength,R20
.dbline 152
; // 发送开始条件
; i2cSendStart();
xcall _i2cSendStart
L25:
.dbline 153
L26:
.dbline 153
; while(I2cState);
lds R2,_I2cState
tst R2
brne L25
.dbline 154
; return(I2cNotAck);
lds R16,_I2cNotAck
.dbline -2
L21:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym l i 1 c
.dbsym r length 20 i
.dbsym r deviceAddr 22 c
.dbend
.dbfunc e i2cMasterReceive _i2cMasterReceive fc
; i -> <dead>
; length -> R20,R21
; deviceAddr -> R22
.even
_i2cMasterReceive::
xcall push_gset2
movw R20,R18
mov R22,R16
.dbline -1
.dbline 158
; }
;
; unsigned char i2cMasterReceive(unsigned char deviceAddr, unsigned int length)
; {
L29:
.dbline 161
L30:
.dbline 161
; unsigned char i;
; // 等待总线准备完成
; while(I2cState);
lds R2,_I2cState
tst R2
brne L29
.dbline 163
; // 设置状态
; I2cState = I2C_MASTER_RX;
ldi R24,3
sts _I2cState,R24
.dbline 165
; // 保存数据
; I2cDeviceAddrRW = (deviceAddr|0x01); // RW 为1 : 读操作
mov R24,R22
ori R24,1
sts _I2cDeviceAddrRW,R24
.dbline 166
; I2cReceiveDataIndex = 0;
clr R2
clr R3
sts _I2cReceiveDataIndex+1,R3
sts _I2cReceiveDataIndex,R2
.dbline 167
; if(length)
cpi R20,0
cpc R20,R21
breq L32
X0:
.dbline 168
; {
.dbline 169
; I2cReceiveDataLength = length;
sts _I2cReceiveDataLength+1,R21
sts _I2cReceiveDataLength,R20
.dbline 170
; EnFlex = 0;
clr R2
sts _EnFlex,R2
.dbline 171
; }
xjmp L33
L32:
.dbline 173
; else
; {
.dbline 174
; I2cReceiveDataLength = 0; //如果此值在此不被清零,那么一旦它大于2就会使中断不能到达修改长度的分支
clr R2
clr R3
sts _I2cReceiveDataLength+1,R3
sts _I2cReceiveDataLength,R2
.dbline 175
; EnFlex = 0xff;
ldi R24,255
sts _EnFlex,R24
.dbline 176
; }
L33:
.dbline 178
; // 发送开始条件
; i2cSendStart();
xcall _i2cSendStart
L34:
.dbline 180
L35:
.dbline 180
; //等待数据准备好
; while(I2cState);
lds R2,_I2cState
tst R2
brne L34
.dbline 181
; return(I2cNotAck);
lds R16,_I2cNotAck
.dbline -2
L28:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym l i 1 c
.dbsym r length 20 i
.dbsym r deviceAddr 22 c
.dbend
.dbfunc e i2cMasterSendNI _i2cMasterSendNI fc
; retval -> R20
; data -> R22,R23
; length -> R10
; deviceAddr -> R12
.even
_i2cMasterSendNI::
xcall push_gset4
mov R10,R18
mov R12,R16
ldd R22,y+8
ldd R23,y+9
.dbline -1
.dbline 189
; }
;
; /************************************************************************/
; /* 无中断的主机数据发送
; */
; /************************************************************************/
; unsigned char i2cMasterSendNI(unsigned char deviceAddr, unsigned char length, unsigned char* data)
; {
.dbline 190
; unsigned char retval = I2C_OK;
clr R20
.dbline 193
;
; // 关I2C中断
; TWCR&=~(1<<TWIE);
in R24,0x36
andi R24,254
out 0x36,R24
.dbline 196
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -