📄 i2c.s
字号:
.module I2C.c
.area text(rom, con, rel)
.dbfile G:\Mega8程序\TCXO评估板\Main\I2C.c
.dbfunc e TWI_init _TWI_init fV
.even
_TWI_init::
.dbline -1
.dbline 52
; #include<iom8v.h>
; /* AT2402C地址
; 1 0 1 0 A2 A1 A0 R/W
; 前4位为AT240X系列的特征字
; 后3位为可编程位
; 最后一位为读写位
; */
; #define rd_device_add 0xa1 //读地址:0b10100001
; #define wr_device_add 0xa0 //写地址:0b10100000
;
; /*TWI状态定义----MT 主方式传输 MR 主方式接收*/
; #define START 0x08
; #define RE_START 0x10
;
; #define MT_SLA_ACK 0x18
; #define MT_SLA_NOACK 0x20
; #define MT_DATA_ACK 0x28
; #define MT_DATA_NOACK 0x30
;
; #define MR_SLA_ACK 0x40
; #define MR_SLA_NOACK 0x48
; #define MR_DATA_ACK 0x50
; #define MR_DATA_NOACK 0x58
;
;
; #define EE_READ 0xf0
; #define EE_READ_OK 0x50
; #define EE_WRITE 0x0f
; #define EE_WRITE_OK 0x05
; #define EE_WRITE_OVER 0xa5
;
; #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE))
; //清除中断标志位,在总线上发出起始信号,激活TWI功能,开放TWI中断
; #define Stop() (TWCR=((1<<TWINT)|(1<<TWSTO)|(1<<TWEN))&(~(1<<TWIE)))
; //清除中断标志位,在总线上发出终止信号,激活TWI功能,关闭TWI中断
; #define TestAck() (TWSR&0xf8)
; //TWSR--I2C状态寄存器,检查TWI状态,应该将预分频位屏蔽(第三位是保留位)
; #define MT_NACK (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE))
; //清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下不对SDA线作应答
; #define MT_ACK (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA))
; //清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下对SDA线作应答
; #define TWItransmit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE);}
; //写入8位数据到数据寄存器中,同时清除中断标志位,使能TWI功能,开放TWI中断
;
; extern void delay_ms(unsigned int time);
;
; unsigned char charData;//TWI中断中,传送的数据
; unsigned char charAddr;//TWI中断中,数据所处的EEPROM地址
; unsigned char charState;//TWI中断中,中断所处的状态
;
; void TWI_init(void)
; {
.dbline 53
; charState=EE_READ;
ldi R24,240
sts _charState,R24
.dbline 54
; TWBR=0x20;//波特率寄存器,正常情况下应不小于10
ldi R24,32
out 0x0,R24
.dbline 55
; TWSR=0x00;//TWI状态寄存器,时钟分频值1
clr R2
out 0x1,R2
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.area vector(rom, abs)
.org 34
rjmp _TWI_Ready
.area text(rom, con, rel)
.dbfile G:\Mega8程序\TCXO评估板\Main\I2C.c
.dbfunc e TWI_Ready _TWI_Ready fV
.even
_TWI_Ready::
st -y,R2
st -y,R16
st -y,R17
st -y,R24
st -y,R25
st -y,R30
in R2,0x3f
st -y,R2
.dbline -1
.dbline 74
; }
;
; /**********************ATEEPROM读写过程*********************************
; 字节写:Start→器件地址&W→应答→选ROM地址→应答→写数据→应答→Stop
; 中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→MT_DATA_ACK(数据)(STOP中止)
;
; 页面写:Start→器件地址&W→应答→选ROM地址→应答→写数据→应答→写NEXT地址数据→应答→。。。写NEXT地址数据→应答→Stop
; 中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→MT_DATA_ACK(数据)→MT_DATA_ACK(数据)→。。。MT_DATA_ACK(数据)(STOP中止)
;
; 字节读:Start→器件地址&W→应答→选ROM地址→应答→Restart→器件地址&R→应答→读数据→无应答→Stop
; 中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→RE_START→MR_SLA_ACK→MR_DATA_NOACK(STOP中止)
;
; 页面读:Start→器件地址&W→应答→选ROM地址→应答→Restart→器件地址&R→应答→读数据→应答→读NEXT地址数据→应答→。。。读NEXT地址数据→无应答→Stop
; 中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→RE_START→MR_SLA_ACK→MR_DATA_ACK→MR_DATA_ACK→。。。MR_DATA_NOACK(STOP中止)
; *************************************************************************/
;
; #pragma interrupt_handler TWI_Ready:iv_TWI//TWI中断处理
; void TWI_Ready(void)
; {
.dbline 75
; switch (TestAck())//检查状态标志字
in R16,0x1
clr R17
andi R16,248
andi R17,0
cpi R16,24
ldi R30,0
cpc R17,R30
breq L8
ldi R24,24
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L21
L20:
cpi R16,8
ldi R30,0
cpc R17,R30
breq L6
cpi R16,8
ldi R30,0
cpc R17,R30
brge X2
rjmp L3
X2:
L22:
cpi R16,16
ldi R30,0
cpc R17,R30
breq L7
rjmp L3
L21:
cpi R16,64
ldi R30,0
cpc R17,R30
brne X3
rjmp L18
X3:
ldi R24,64
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L24
L23:
cpi R16,40
ldi R30,0
cpc R17,R30
breq L9
rjmp L3
L24:
cpi R16,88
ldi R30,0
cpc R17,R30
brne X4
rjmp L19
X4:
rjmp L3
X0:
.dbline 76
; {
L6:
.dbline 78
; case START:
; {
.dbline 79
; TWItransmit(wr_device_add);
.dbline 79
ldi R24,160
out 0x3,R24
.dbline 79
ldi R24,133
out 0x36,R24
.dbline 79
.dbline 79
.dbline 81
; //选取I2C从器件地址,进行主控写模式
; break;
rjmp L4
L7:
.dbline 84
; }
; case RE_START:
; {
.dbline 85
; TWItransmit(rd_device_add);
.dbline 85
ldi R24,161
out 0x3,R24
.dbline 85
ldi R24,133
out 0x36,R24
.dbline 85
.dbline 85
.dbline 87
; //选取I2C从器件地址,进行主控读模式
; break;
rjmp L4
L8:
.dbline 91
; }
; case MT_SLA_ACK:
; //Slave器件被识别并产生应答
; {
.dbline 92
; TWItransmit(charAddr);
.dbline 92
lds R2,_charAddr
out 0x3,R2
.dbline 92
ldi R24,133
out 0x36,R24
.dbline 92
.dbline 92
.dbline 94
; //写24C02ROM的字地址
; break;
rjmp L4
L9:
.dbline 98
; }
; case MT_DATA_ACK:
; //主控发送数据,并得到响应
; {
.dbline 99
; switch(charState)
lds R16,_charState
clr R17
cpi R16,165
ldi R30,0
cpc R17,R30
breq L14
ldi R24,165
ldi R25,0
cp R24,R16
cpc R25,R17
brlt L17
L16:
cpi R16,15
ldi R30,0
cpc R17,R30
breq L13
rjmp L4
L17:
cpi R16,240
ldi R30,0
cpc R17,R30
breq L15
rjmp L4
X1:
.dbline 100
; {
L13:
.dbline 102
; case EE_WRITE://写数据到24C02的ROM
; {
.dbline 103
; TWItransmit(charData);
.dbline 103
lds R2,_charData
out 0x3,R2
.dbline 103
ldi R24,133
out 0x36,R24
.dbline 103
.dbline 103
.dbline 104
; charState=EE_WRITE_OVER;
ldi R24,165
sts _charState,R24
.dbline 105
; break;
rjmp L4
L14:
.dbline 108
; }
; case EE_WRITE_OVER://I2C停止
; {
.dbline 109
; Stop();
ldi R24,148
out 0x36,R24
.dbline 110
; charState=EE_WRITE_OK;
ldi R24,5
sts _charState,R24
.dbline 111
; break;
rjmp L4
L15:
.dbline 114
; }
; case EE_READ:
; {
.dbline 115
; Start();
ldi R24,165
out 0x36,R24
.dbline 116
; break;
.dbline 120
; }
; //I2C重新启动
; }
; break;
rjmp L4
L18:
.dbline 123
; }
; case MR_SLA_ACK:
; {
.dbline 124
; MT_NACK;
ldi R24,133
out 0x36,R24
.dbline 125
; break;
rjmp L4
L19:
.dbline 129
; }
; //启动主I2C读方式
; case MR_DATA_NOACK:
; {
.dbline 130
; charData=TWDR;
in R2,0x3
sts _charData,R2
.dbline 131
; Stop();
ldi R24,148
out 0x36,R24
.dbline 132
; charState=EE_READ_OK;
ldi R24,80
sts _charState,R24
.dbline 133
; break;
rjmp L4
L3:
.dbline 137
ldi R24,148
out 0x36,R24
.dbline 138
L4:
.dbline -2
L2:
ld R2,y+
out 0x3f,R2
ld R30,y+
ld R25,y+
ld R24,y+
ld R17,y+
ld R16,y+
ld R2,y+
.dbline 0 ; func end
reti
.dbend
.dbfunc e i2c_write _i2c_write fV
; RomAddress -> R20
; Wdata -> R22
.even
_i2c_write::
rcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 145
; }
; //读取I2C接收数据,I2C停止
; default:
; Stop();//I2C停止
; }
; }
;
; /*
; 常用TWI操作(主模式写和主模式读)
; */
; void i2c_write(unsigned char Wdata,unsigned char RomAddress)
; {
.dbline 146
; charData=Wdata;//I2C总线写一个字节
sts _charData,R22
.dbline 147
; charAddr=RomAddress;//返回0:写成功
sts _charAddr,R20
.dbline 148
; charState=EE_WRITE;//返回非0:写失败
ldi R24,15
sts _charState,R24
.dbline 149
; Start();//I2C启动(TWI中断启动)
ldi R24,165
out 0x36,R24
L26:
.dbline 150
L27:
.dbline 150
; while(charState!=EE_WRITE_OK);
lds R24,_charState
cpi R24,5
brne L26
.dbline 151
; delay_ms(10);
ldi R16,10
ldi R17,0
rcall _delay_ms
.dbline -2
L25:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r RomAddress 20 c
.dbsym r Wdata 22 c
.dbend
.dbfunc e i2c_read _i2c_read fc
; RomAddress -> R16
.even
_i2c_read::
.dbline -1
.dbline 154
; }
; unsigned char i2c_read(unsigned char RomAddress)
; {
.dbline 155
; charAddr=RomAddress;
sts _charAddr,R16
.dbline 156
; charState=EE_READ;
ldi R24,240
sts _charState,R24
.dbline 157
; Start();//I2C启动
ldi R24,165
out 0x36,R24
L30:
.dbline 158
L31:
.dbline 158
; while(charState!=EE_READ_OK);
lds R24,_charState
cpi R24,80
brne L30
.dbline 159
; return charData;
lds R16,_charData
.dbline -2
L29:
.dbline 0 ; func end
ret
.dbsym r RomAddress 16 c
.dbend
.area bss(ram, con, rel)
.dbfile G:\Mega8程序\TCXO评估板\Main\I2C.c
_charState::
.blkb 1
.dbsym e charState _charState c
_charAddr::
.blkb 1
.dbsym e charAddr _charAddr c
_charData::
.blkb 1
.dbsym e charData _charData c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -