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

📄 twi.s

📁 avr 单片机twi源程序 功能:实现TWI主从机通讯.
💻 S
字号:
	.module twi.c
	.area data(ram, con, rel)
_main_tmp::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile F:\2007电子设计\古欣\twitest\twi_slave_test\twi.c
	.dbsym e main_tmp _main_tmp c
	.area text(rom, con, rel)
	.dbfile F:\2007电子设计\古欣\twitest\twi_slave_test\twi.c
	.dbfunc e twi_master_init _twi_master_init fV
	.even
_twi_master_init::
	.dbline -1
	.dbline 9
; #include "config.h"
; 
; volatile uint8 main_tmp=0;
; //extern volatile uint8 main_tmp=0;
; 
; //TWI master initialize
; // bit rate:100
; void twi_master_init(void)
; {
	.dbline 10
;  TWCR= 0x00; //disable twi
	clr R2
	out 0x36,R2
	.dbline 11
;  TWBR= 0x64; //set bit rate
	ldi R24,100
	out 0x0,R24
	.dbline 12
;  TWSR= 0x00; //set prescale
	out 0x1,R2
	.dbline 13
;  TWAR= 0x00; //set slave address
	out 0x2,R2
	.dbline 14
;  TWCR= 0x04; //enable twi
	ldi R24,4
	out 0x36,R24
	.dbline -2
L1:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e twi_slave_init _twi_slave_init fV
;            add -> R16
	.even
_twi_slave_init::
	.dbline -1
	.dbline 20
; }
; 
; //TWI slave initialize
; // bit rate:100
; void twi_slave_init(uint8 add)
; {
	.dbline 21
;  TWCR= 0x00; //disable twi
	clr R2
	out 0x36,R2
	.dbline 22
;  TWBR= 0x64; //set bit rate
	ldi R24,100
	out 0x0,R24
	.dbline 23
;  TWSR= 0x00; //set prescale
	out 0x1,R2
	.dbline 24
;  TWAR= add; //set slave address 从机地址为 0x01
	out 0x2,R16
	.dbline 25
;  TWCR= (1<<TWEN)|(1<<TWEA)|(1<<TWIE); //enable twi
	ldi R24,69
	out 0x36,R24
	.dbline -2
L2:
	.dbline 0 ; func end
	ret
	.dbsym r add 16 c
	.dbend
	.dbfunc e i2c_start _i2c_start fV
	.even
_i2c_start::
	.dbline -1
	.dbline 31
;  //TWEN必须置位以使能TWI接口。TWEA也要置位以使主机寻址到自己(从机地址或广播) 时返回确认信息ACK
; }
; 
; //总线上起动开始条件
; void i2c_start(void)
; {
	.dbline 32
; 	TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	ldi R24,164
	out 0x36,R24
L4:
	.dbline 33
L5:
	.dbline 33
;    	while (!(TWCR & (1<<TWINT))); //等待START 信号成功发送
	in R2,0x36
	sbrs R2,7
	rjmp L4
	.dbline -2
L3:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e i2c_write _i2c_write fc
;           data -> R16
	.even
_i2c_write::
	.dbline -1
	.dbline 39
; }
; 
; //把一个字节数据输入器件, 返回TWI状态
; //发送地址和数据都可以使用本函数
; uint8 i2c_write(uint8 data)
; {
	.dbline 40
; 	TWDR = data; 
	out 0x3,R16
	.dbline 41
;    	TWCR = (1<<TWINT)|(1<<TWEN); 
	ldi R24,132
	out 0x36,R24
L8:
	.dbline 42
L9:
	.dbline 42
;    	while (!(TWCR & (1<<TWINT)));
	in R2,0x36
	sbrs R2,7
	rjmp L8
	.dbline 43
;    	_NOP();
	nop
	.dbline 44
;    	return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
	in R16,0x1
	andi R16,248
	.dbline -2
L7:
	.dbline 0 ; func end
	ret
	.dbsym r data 16 c
	.dbend
	.dbfunc e i2c_read _i2c_read fc
	.even
_i2c_read::
	.dbline -1
	.dbline 49
; }
; 
; //从器件读出一个字节
; uint8 i2c_read(void)
; {
	.dbline 50
;    	TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN); 
	ldi R24,196
	out 0x36,R24
L12:
	.dbline 51
L13:
	.dbline 51
;    	while (!(TWCR & (1<<TWINT)));
	in R2,0x36
	sbrs R2,7
	rjmp L12
	.dbline 52
;    	return(TWDR);
	in R16,0x3
	.dbline -2
L11:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e i2c_stop _i2c_stop fV
	.even
_i2c_stop::
	.dbline -1
	.dbline 57
; }
; 
; //总线上起动停止条件 
; void i2c_stop(void) 
; { 
	.dbline 58
;    TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); 
	ldi R24,148
	out 0x36,R24
	.dbline -2
L15:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e i2c_maste_transt _i2c_maste_transt fV
;           data -> R20
;           addr -> R22
	.even
_i2c_maste_transt::
	xcall push_gset2
	mov R20,R18
	mov R22,R16
	.dbline -1
	.dbline 63
; }
; 
; //操作步骤: 启动,发送地址,发送数据,关闭总线
; void i2c_maste_transt(uint8 addr, uint8 data)
; {
	.dbline 64
;  i2c_start();
	xcall _i2c_start
	.dbline 65
;  if(i2c_write(addr)==TW_MT_SLA_ACK) //发送地址成功并收到ACK
	mov R16,R22
	xcall _i2c_write
	cpi R16,24
	brne L17
	.dbline 66
;  {
	.dbline 67
;   i2c_write(data);
	mov R16,R20
	xcall _i2c_write
	.dbline 68
;  }
L17:
	.dbline 69
;  i2c_stop();
	xcall _i2c_stop
	.dbline -2
L16:
	xcall pop_gset2
	.dbline 0 ; func end
	ret
	.dbsym r data 20 c
	.dbsym r addr 22 c
	.dbend
	.area vector(rom, abs)
	.org 68
	jmp _twi_isr
	.area text(rom, con, rel)
	.dbfile F:\2007电子设计\古欣\twitest\twi_slave_test\twi.c
	.dbfunc e twi_isr _twi_isr fV
	.even
_twi_isr::
	xcall push_lset
	xcall push_gset1
	.dbline -1
	.dbline 75
; }
; 
; #if TWI_MOD==0 //从机模式
; #pragma interrupt_handler twi_isr:18
; void twi_isr(void)
; {
	.dbline 77
;  //twi event
;  switch (TWSR&0xF8)
	in R20,0x1
	clr R21
	andi R20,248
	andi R21,0
	cpi R20,144
	ldi R30,0
	cpc R21,R30
	brne X3
	xjmp L25
X3:
	ldi R24,144
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brge X4
	xjmp L33
X4:
L32:
	cpi R20,112
	ldi R30,0
	cpc R21,R30
	brne X5
	xjmp L23
X5:
	ldi R24,112
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L35
L34:
	cpi R20,96
	ldi R30,0
	cpc R21,R30
	brne X6
	xjmp L23
X6:
	ldi R24,96
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L37
L36:
	cpi R20,0
	cpc R20,R21
	brne X7
	xjmp L31
X7:
X0:
	xjmp L21
L37:
	cpi R20,104
	ldi R30,0
	cpc R21,R30
	brne X8
	xjmp L23
X8:
	xjmp L21
L35:
	cpi R20,128
	ldi R30,0
	cpc R21,R30
	brne X9
	xjmp L24
X9:
	ldi R24,128
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L39
L38:
	cpi R20,120
	ldi R30,0
	cpc R21,R30
	brne X10
	xjmp L23
X10:
	xjmp L21
L39:
	cpi R20,136
	ldi R30,0
	cpc R21,R30
	brne X11
	xjmp L24
X11:
	xjmp L21
L33:
	cpi R20,176
	ldi R30,0
	cpc R21,R30
	brne X12
	xjmp L27
X12:
	ldi R24,176
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L41
L40:
	cpi R20,160
	ldi R30,0
	cpc R21,R30
	brne X13
	xjmp L26
X13:
	ldi R24,160
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L43
L42:
	cpi R20,152
	ldi R30,0
	cpc R21,R30
	breq L25
	xjmp L21
L43:
	cpi R20,168
	ldi R30,0
	cpc R21,R30
	brne X14
	xjmp L27
X14:
	xjmp L21
L41:
	cpi R20,192
	ldi R30,0
	cpc R21,R30
	brne X15
	xjmp L29
X15:
	ldi R24,192
	ldi R25,0
	cp R24,R20
	cpc R25,R21
	brlt L45
L44:
	cpi R20,184
	ldi R30,0
	cpc R21,R30
	breq L28
	xjmp L21
L45:
	cpi R20,200
	ldi R30,0
	cpc R21,R30
	breq L29
	cpi R20,200
	ldi R30,0
	cpc R21,R30
	brlt L21
L46:
	cpi R20,248
	ldi R30,0
	cpc R21,R30
	breq L21
	xjmp L21
X1:
	.dbline 78
;  {
L23:
	.dbline 84
;  //从接收
;  case TW_SR_SLA_ACK:
;  case TW_SR_ARB_LOST_SLA_ACK:
;  case TW_SR_GCALL_ACK:
;  case TW_SR_ARB_LOST_GCALL_ACK:
;  	  Twi_Ack();  //返回ACK
	.dbline 84
	in R24,0x36
	andi R24,15
	ori R24,192
	out 0x36,R24
	.dbline 84
	.dbline 84
	.dbline 85
; 	  break;
	xjmp L21
L24:
	.dbline 88
;  case TW_SR_DATA_ACK:
;  case TW_SR_DATA_NACK:
;  	  main_tmp = TWDR;
	in R2,0x3
	sts _main_tmp,R2
	.dbline 89
;   	  PORTA = ~ TWDR; //接收数据并显示
	in R2,0x3
	com R2
	out 0x1b,R2
	.dbline 90
;  	  Twi_Ack();  //返回ACK
	.dbline 90
	in R24,0x36
	andi R24,15
	ori R24,192
	out 0x36,R24
	.dbline 90
	.dbline 90
	.dbline 91
; 	  break;
	xjmp L21
L25:
	.dbline 94
;  case TW_SR_GCALL_DATA_ACK:
;  case TW_SR_GCALL_DATA_NACK:	
;  	  Twi_Ack();  //返回ACK
	.dbline 94
	in R24,0x36
	andi R24,15
	ori R24,192
	out 0x36,R24
	.dbline 94
	.dbline 94
	.dbline 95
; 	  break;
	xjmp L21
L26:
	.dbline 97
;  case TW_SR_STOP:
;  	  Twi_Ack(); 
	.dbline 97
	in R24,0x36
	andi R24,15
	ori R24,192
	out 0x36,R24
	.dbline 97
	.dbline 97
	.dbline 98
; 	  break;
	xjmp L21
L27:
	.dbline 104
;  //从发送*****************************
;  
;    case TW_ST_SLA_ACK:               // 0xA8: 自己的SLA+R 已经被接收,ACK 已返回 
;    case TW_ST_ARB_LOST_SLA_ACK:// 0xB0: SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收,ACK 已返回 
;       // 被选中为从读出 (数据将从传回主机) 
; 	  TWDR=main_tmp;  //发送全局变量中值
	lds R2,_main_tmp
	out 0x3,R2
	.dbline 105
; 	  Twi_Ack(); 		
	.dbline 105
	in R24,0x36
	andi R24,15
	ori R24,192
	out 0x36,R24
	.dbline 105
	.dbline 105
	.dbline 106
; 	  break;    
	xjmp L21
L28:
	.dbline 109
;   case TW_ST_DATA_ACK:            // 0xB8: TWDR 里数据已经发送,接收到ACK 
;       //发送数据位 
; 	 TWDR=main_tmp;
	lds R2,_main_tmp
	out 0x3,R2
	.dbline 110
;      break;    
	xjmp L21
L29:
	.dbline 115
;    case TW_ST_DATA_NACK:            // 0xC0: TWDR 里数据已经发送接收到NOT ACK 
;    case TW_ST_LAST_DATA:            // 0xC8: TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK 
;       // 全部完成 
;       // 从方式开放 
;       Twi_NoAcK(); 
	.dbline 115
	in R24,0x36
	andi R24,15
	ori R24,128
	out 0x36,R24
	.dbline 115
	.dbline 115
	.dbline 116
; 	  twi_slave_init(0x50);        //重新回到初始化状态,等待接收模式的到来
	ldi R16,80
	xcall _twi_slave_init
	.dbline 117
;       break; 
	xjmp L21
X2:
	.dbline 120
;    case TW_NO_INFO:                 // 0xF8: 没有相关的状态信息;TWINT = “0” 
;       // 无操作 
; 	  break; 
L31:
	.dbline 123
	in R24,0x36
	andi R24,15
	ori R24,208
	out 0x36,R24
	.dbline 124
	.dbline 126
L21:
	.dbline -2
L19:
	xcall pop_gset1
	xcall pop_lset
	.dbline 0 ; func end
	reti
	.dbend

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -