⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.s

📁 详细介绍M8两版间通讯
💻 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 + -