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

📄 i2c.s

📁 详细介绍M8两版间通讯
💻 S
字号:
	.module I2C.c
	.area text(rom, con, rel)
	.dbfile G:\Mega8程序\TCXO评估板\LedShow\I2C.c
	.dbfunc e TWI_init _TWI_init fV
	.even
_TWI_init::
	.dbline -1
	.dbline 79
; /*******************************************************
; 本部分为TWI总线的被控器部分程序,可以完成被控接收、被控发送数据
; 其工作方式与At240×系列的EEPROM的字节读写相同
; 目前问题是EEPROM的读写速度太慢,无法跟上TWI总线速度。
; *///////////////////////////////////////////////////////
; 
; #include<iom8v.h>
; #include <macros.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
; 
; //SR-从机方式接收  ST-从机方式传输  ALL-广播 NOCTRL-主机丢失控制权
; #define SR_SLA_ACK					0x60
; #define SR_SLA_ACK_NOCTRL		0x68
; #define SR_ALL_ACK					0x70
; #define SR_ALL_ACK_NOCTRL		0x78
; #define SR_DATA_ACK					0X80
; #define SR_DATA_NOACK				0X88
; #define SR_ALL_DATA_ACK			0x90
; #define SR_ALL_DATA_NOACK		0x98
; #define SR_STOP_RESTART			0xa0
; 
; #define ST_SLA_ACK					0xa8
; #define ST_SLA_ACK_NOCTRL		0xb0
; #define ST_DATA_ACK					0xb8
; #define ST_DATA_NOACK				0xc0
; #define ST_LAST_DATA_ACK		0xc8
; 
; ///////////////////////////////////////////////////////////
; #define EE_READ							0xf0
; #define EE_READ_OK					0x50
; #define EE_WRITE						0x0f
; #define EE_WRITE_OK					0x05
; #define EE_WRITE_OVER				0xa5
; 
; #define TestAck() (TWSR&0xf8)
; //TWSR--I2C状态寄存器,检查TWI状态,应该将预分频位屏蔽(第三位是保留位)
; 
; #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 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 char cDataBuff[];
; extern void rom_write(unsigned int Address,unsigned  char Data);
; extern unsigned char rom_read(unsigned int Address);
; 
; unsigned char charData;//TWI中断中,传送的数据
; unsigned char charAddr;//TWI中断中,数据所处的EEPROM地址
; unsigned char charState;//TWI中断中,中断所处的状态
; 
; void TWI_init(void)
;  {
	.dbline 80
; 	DDRC&=0b11001111;//设置PC4、PC5为输入
	in R24,0x14
	andi R24,207
	out 0x14,R24
	.dbline 81
; 	PORTC|=0b00110000;//将SDA、SCL线拉高(内置上拉电阻)
	in R24,0x15
	ori R24,48
	out 0x15,R24
	.dbline 82
; 	charState=EE_READ;
	ldi R24,240
	sts _charState,R24
	.dbline 83
; 	TWBR=0x00;//波特率寄存器,主机正常情况下应不小于10
	clr R2
	out 0x0,R2
	.dbline 84
; 	TWSR=0x00;//TWI状态寄存器,时钟分频值1
	out 0x1,R2
	.dbline 85
; 	TWAR=0xa0;/*被控器地址寄存器。0xa0为AT2402的地址,可以用ATMEGA8来模拟AT2402。
	ldi R24,160
	out 0x2,R24
	.dbline 87
; 	 						作为从机,应该将被控器的地址写入。注意不要和其他器件相同*/
; 	TWCR=(TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA));//清除中断标志位,使能TWI功能,开放TWI中断
	ldi R24,197
	out 0x36,R24
	out 0x36,R24
	.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评估板\LedShow\I2C.c
	.area data(ram, con, rel)
	.dbfile G:\Mega8程序\TCXO评估板\LedShow\I2C.c
L3:
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile G:\Mega8程序\TCXO评估板\LedShow\I2C.c
	.area text(rom, con, rel)
	.dbfile G:\Mega8程序\TCXO评估板\LedShow\I2C.c
	.dbfunc e TWI_Ready _TWI_Ready fV
	.dbsym s charIndex L3 c
;       charTemp -> R20
;      TWI_STATE -> R22
	.even
_TWI_Ready::
	st -y,R2
	st -y,R3
	st -y,R16
	st -y,R17
	st -y,R24
	st -y,R25
	st -y,R30
	st -y,R31
	in R2,0x3f
	st -y,R2
	rcall push_gset2
	.dbline -1
	.dbline 91
;  }
; #pragma interrupt_handler TWI_Ready:iv_TWI//TWI中断处理
; void TWI_Ready(void)
;  {
	.dbline 95
;  	static unsigned char charIndex=0;
;  	unsigned char charTemp;
;  	unsigned char TWI_STATE;
; 	TWI_STATE=TestAck();
	in R22,0x1
	andi R22,248
	.dbline 96
; 	switch (TWI_STATE)//检查状态标志字
	mov R20,R22
	clr R21
	cpi R20,160
	ldi R30,0
	cpc R21,R30
	brne X2
	rjmp L15
X2:
	ldi R24,160
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L20
L19:
	cpi R20,96
	ldi R30,0
	cpc R21,R30
	breq L7
	cpi R20,96
	ldi R30,0
	cpc R21,R30
	brge X3
	rjmp L4
X3:
L21:
	cpi R20,128
	ldi R30,0
	cpc R21,R30
	breq L8
	rjmp L4
L20:
	cpi R20,184
	ldi R30,0
	cpc R21,R30
	brne X4
	rjmp L17
X4:
	ldi R24,184
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L23
L22:
	cpi R20,168
	ldi R30,0
	cpc R21,R30
	brne X5
	rjmp L16
X5:
	rjmp L4
L23:
	cpi R20,192
	ldi R30,0
	cpc R21,R30
	brne X6
	rjmp L18
X6:
	rjmp L4
X0:
	.dbline 97
; 	 {
L7:
	.dbline 99
; 	 	case SR_SLA_ACK:
; 	 	 {
	.dbline 100
; 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 101
; 	 	 }
	.dbline 102
; 	 	break;
	rjmp L5
L8:
	.dbline 104
; 	 	case SR_DATA_ACK:
; 	 	 {
	.dbline 105
; 	 	 	switch (charState)
	lds R20,_charState
	clr R21
	cpi R20,80
	ldi R30,0
	cpc R21,R30
	breq L13
	cpi R20,80
	ldi R30,0
	cpc R21,R30
	brge X7
	rjmp L5
X7:
L14:
	cpi R20,240
	ldi R30,0
	cpc R21,R30
	breq L12
	rjmp L5
X1:
	.dbline 106
; 	 	 	 {
L12:
	.dbline 108
; 	 	 	 	case EE_READ://进入开始读取数据状态,此处即将读取的数据为ROM的Index
; 	 	 	 	 {
	.dbline 109
; 	 	 	 	 	PORTC^=(0b00001000);//闪亮LED
	ldi R24,8
	in R2,0x15
	eor R2,R24
	out 0x15,R2
	.dbline 110
; 	 	 	 	 	charAddr=TWDR;
	in R2,0x3
	sts _charAddr,R2
	.dbline 111
; 	 	 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 112
; 	 	 	 	 	charState=EE_READ_OK;
	ldi R24,80
	sts _charState,R24
	.dbline 113
; 	 	 	 	 }
	.dbline 114
; 	 	 	 	break;
	rjmp L5
L13:
	.dbline 116
; 	 	 	 	case EE_READ_OK://进入读取数据完成状态此处即将读取的数据为ROM->Index的数据
; 	 	 	 	 {
	.dbline 117
; 	 	 	 	 	charData=TWDR;
	in R2,0x3
	sts _charData,R2
	.dbline 118
; 	 	 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 120
; 					//rom_write((unsigned char)charAddr,charData);
; 	 	 	 	 	charState=EE_READ;
	ldi R24,240
	sts _charState,R24
	.dbline 121
; 	 	 	 	 	charIndex+=3;
	lds R24,L3
	subi R24,253    ; addi 3
	sts L3,R24
	.dbline 122
; 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
	andi R24,31
	sts L3,R24
	.dbline 123
; 	 	 	 	 	cDataBuff[charIndex--]=0x0a;//间隔空格符
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	ldi R24,10
	std z+0,R24
	.dbline 124
; 	 	 	 	 	charTemp=charAddr%10;
	ldi R17,10
	lds R16,_charAddr
	rcall mod8u
	mov R20,R16
	.dbline 125
; 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
	lds R24,L3
	andi R24,31
	sts L3,R24
	.dbline 126
; 	 	 	 	 	cDataBuff[charIndex--]=charTemp;
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R20
	.dbline 127
; 	 	 	 	 	charAddr/=10;
	ldi R17,10
	lds R16,_charAddr
	rcall div8u
	sts _charAddr,R16
	.dbline 128
; 	 	 	 	 	charTemp=charAddr%10;
	ldi R17,10
	rcall mod8u
	mov R20,R16
	.dbline 129
; 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
	lds R24,L3
	andi R24,31
	sts L3,R24
	.dbline 130
; 	 	 	 	 	cDataBuff[charIndex--]=charTemp;
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R20
	.dbline 131
; 	 	 	 	 	charAddr/=10;
	ldi R17,10
	lds R16,_charAddr
	rcall div8u
	sts _charAddr,R16
	.dbline 132
; 	 	 	 	 	cDataBuff[charIndex]=charAddr;
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	lds R30,L3
	clr R31
	add R30,R24
	adc R31,R25
	mov R2,R16
	std z+0,R2
	.dbline 133
; 	 	 	 	 	charIndex+=4;//指向末尾空位
	lds R24,L3
	subi R24,252    ; addi 4
	sts L3,R24
	.dbline 134
; 	 	 	 	 	charIndex+=3;
	subi R24,253    ; addi 3
	sts L3,R24
	.dbline 135
; 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
	andi R24,31
	sts L3,R24
	.dbline 136
; 	 	 	 	 	cDataBuff[charIndex--]=0x0a;//间隔空格符
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	ldi R24,10
	std z+0,R24
	.dbline 137
; 	 	 	 	 	charTemp=charData%10;
	ldi R17,10
	lds R16,_charData
	rcall mod8u
	mov R20,R16
	.dbline 138
; 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
	lds R24,L3
	andi R24,31
	sts L3,R24
	.dbline 139
; 	 	 	 	 	cDataBuff[charIndex--]=charTemp;
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R20
	.dbline 140
; 	 	 	 	 	charData/=10;
	ldi R17,10
	lds R16,_charData
	rcall div8u
	sts _charData,R16
	.dbline 141
; 	 	 	 	 	charTemp=charData%10;
	ldi R17,10
	rcall mod8u
	mov R20,R16
	.dbline 142
; 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
	lds R24,L3
	andi R24,31
	sts L3,R24
	.dbline 143
; 	 	 	 	 	cDataBuff[charIndex--]=charTemp;
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R20
	.dbline 144
; 	 	 	 	 	charData/=10;
	ldi R17,10
	lds R16,_charData
	rcall div8u
	sts _charData,R16
	.dbline 145
; 	 	 	 	 	cDataBuff[charIndex]=charData;
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	lds R30,L3
	clr R31
	add R30,R24
	adc R31,R25
	mov R2,R16
	std z+0,R2
	.dbline 146
; 	 	 	 	 	charIndex+=4;//指向末尾空位
	lds R24,L3
	subi R24,252    ; addi 4
	sts L3,R24
	.dbline 147
; 	 	 	 	 }
	.dbline 148
; 	 	 	 	break;
	.dbline 150
; 	 	 	 }
; 	 	 }
	.dbline 151
; 	 	break;
	rjmp L5
L15:
	.dbline 153
; 	 	case SR_STOP_RESTART://收到STOP信号或者RESTART
; 	 	 {
	.dbline 154
; 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 155
; 	 	 	}
	.dbline 156
; 	 	break;
	rjmp L5
L16:
	.dbline 158
; 	 	case ST_SLA_ACK://收到读信号,将(最后一个-NT_NACK、普通数据-MT_ACK)数据发送出去
; 	 	 {
	.dbline 161
; 	 	 	/*charTemp=rom_read((unsigned int)charAddr);
; 	 	 	TWDR=charTemp;*/
; 	 	 	TWDR=0xdd;//测试用,发送测试数据。MEGA8的EEPROM的读速度跟不上TWI
	ldi R24,221
	out 0x3,R24
	.dbline 162
; 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 163
; 	 	 	}
	.dbline 164
; 	 	break;
	rjmp L5
L17:
	.dbline 166
; 	 	case ST_DATA_ACK://主机要求继续发送数据
; 	 	 {
	.dbline 167
; 	 	 	TWDR=cDataBuff[++charAddr];
	lds R24,_charAddr
	subi R24,255    ; addi 1
	mov R2,R24
	sts _charAddr,R2
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	ldd R2,z+0
	out 0x3,R2
	.dbline 168
; 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 169
; 	 	 	}
	.dbline 170
; 	 	break;
	rjmp L5
L18:
	.dbline 172
; 	 	case ST_DATA_NOACK://数据发送完毕
; 	 	 {
	.dbline 173
; 	 	 	MT_ACK;
	ldi R24,197
	out 0x36,R24
	.dbline 174
; 	 	 	}
	.dbline 175
; 	 	break;
	rjmp L5
L4:
	.dbline 177
	.dbline 178
	sts _charData,R22
	.dbline 179
	lds R24,L3
	subi R24,253    ; addi 3
	sts L3,R24
	.dbline 180
	andi R24,31
	sts L3,R24
	.dbline 181
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	ldi R24,11
	std z+0,R24
	.dbline 182
	ldi R17,10
	lds R16,_charData
	rcall mod8u
	mov R20,R16
	.dbline 183
	lds R24,L3
	andi R24,31
	sts L3,R24
	.dbline 184
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R20
	.dbline 185
	ldi R17,10
	lds R16,_charData
	rcall div8u
	sts _charData,R16
	.dbline 186
	ldi R17,10
	rcall mod8u
	mov R20,R16
	.dbline 187
	lds R24,L3
	andi R24,31
	sts L3,R24
	.dbline 188
	mov R2,R24
	clr R3
	subi R24,1
	sts L3,R24
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	mov R30,R2
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R20
	.dbline 189
	ldi R17,10
	lds R16,_charData
	rcall div8u
	sts _charData,R16
	.dbline 190
	ldi R24,<_cDataBuff
	ldi R25,>_cDataBuff
	lds R30,L3
	clr R31
	add R30,R24
	adc R31,R25
	mov R2,R16
	std z+0,R2
	.dbline 191
	lds R24,L3
	subi R24,252    ; addi 4
	sts L3,R24
	.dbline 192
	ldi R24,197
	out 0x36,R24
	.dbline 193
	.dbline 194
L5:
	.dbline -2
L2:
	rcall pop_gset2
	ld R2,y+
	out 0x3f,R2
	ld R31,y+
	ld R30,y+
	ld R25,y+
	ld R24,y+
	ld R17,y+
	ld R16,y+
	ld R3,y+
	ld R2,y+
	.dbline 0 ; func end
	reti
	.dbsym r charTemp 20 c
	.dbsym r TWI_STATE 22 c
	.dbend
	.area bss(ram, con, rel)
	.dbfile G:\Mega8程序\TCXO评估板\LedShow\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 + -