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

📄 twi.s

📁 avr 单片机twi源程序 功能:实现TWI主从机通讯.
💻 S
字号:
	.module twi.c
	.area text(rom, con, rel)
	.dbfile F:\2007电子设计\古欣\twitest\twi_test\twi.c
	.dbfunc e twi_master_init _twi_master_init fV
	.even
_twi_master_init::
	.dbline -1
	.dbline 7
; 
; #include "config.h"
; 
; //TWI master initialize
; // bit rate:100
; void twi_master_init(void)
; {
	.dbline 8
;  TWCR= 0x00; //disable twi
	clr R2
	out 0x36,R2
	.dbline 9
;  TWBR= 0x64; //set bit rate
	ldi R24,100
	out 0x0,R24
	.dbline 10
;  TWSR= 0x00; //set prescale
	out 0x1,R2
	.dbline 11
;  TWAR= 0x00; //set slave address
	out 0x2,R2
	.dbline 12
;  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 18
; }
; 
; //TWI slave initialize
; // bit rate:100
; void twi_slave_init(uint8 add)
; {
	.dbline 19
;  TWCR= 0x00; //disable twi
	clr R2
	out 0x36,R2
	.dbline 20
;  TWBR= 0x64; //set bit rate
	ldi R24,100
	out 0x0,R24
	.dbline 21
;  TWSR= 0x00; //set prescale
	out 0x1,R2
	.dbline 22
;  TWAR= (add<<1); //set slave address 从机地址为 0x01
	mov R2,R16
	lsl R2
	out 0x2,R2
	.dbline 23
;  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 29
;  //TWEN必须置位以使能TWI接口。TWEA也要置位以使主机寻址到自己(从机地址或广播) 时返回确认信息ACK
; }
; 
; //总线上起动开始条件
; void i2c_start(void)
; {
	.dbline 30
; 	TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	ldi R24,164
	out 0x36,R24
L4:
	.dbline 31
L5:
	.dbline 31
;    	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_addr _i2c_write_addr fc
;            r_w -> R18
;           addr -> R16
	.even
_i2c_write_addr::
	.dbline -1
	.dbline 37
; }
; 
; //把一个字节数据输入器件, 返回TWI状态
; //发送地址,r_w:1为读,0为写
; uint8 i2c_write_addr(uint8 addr,uint8 r_w)
; {
	.dbline 38
;  	if(r_w)
	tst R18
	breq L8
	.dbline 39
; 	{
	.dbline 40
; 	 TWDR = addr|r_w;     //RW 为1:读操作
	mov R2,R16
	or R2,R18
	out 0x3,R2
	.dbline 41
; 	}
	xjmp L9
L8:
	.dbline 43
; 	else
; 	{
	.dbline 44
; 	TWDR = addr & 0xFE;   // RW 为0: 写操作
	mov R24,R16
	andi R24,254
	out 0x3,R24
	.dbline 45
; 	} 
L9:
	.dbline 47
; 
;    	TWCR = (1<<TWINT)|(1<<TWEN); 
	ldi R24,132
	out 0x36,R24
L10:
	.dbline 48
L11:
	.dbline 48
;    	while (!(TWCR & (1<<TWINT)));
	in R2,0x36
	sbrs R2,7
	rjmp L10
	.dbline 49
;    	_NOP();
	nop
	.dbline 50
;    	return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
	in R16,0x1
	andi R16,248
	.dbline -2
L7:
	.dbline 0 ; func end
	ret
	.dbsym r r_w 18 c
	.dbsym r addr 16 c
	.dbend
	.dbfunc e i2c_write_data _i2c_write_data fc
;           data -> R16
	.even
_i2c_write_data::
	.dbline -1
	.dbline 56
; }
; 
; //把一个字节数据输入器件, 返回TWI状态
; //发送数据
; uint8 i2c_write_data(uint8 data)
; {
	.dbline 57
; 	TWDR = data;
	out 0x3,R16
	.dbline 58
;    	TWCR = (1<<TWINT)|(1<<TWEN); 
	ldi R24,132
	out 0x36,R24
L14:
	.dbline 59
L15:
	.dbline 59
;    	while (!(TWCR & (1<<TWINT)));
	in R2,0x36
	sbrs R2,7
	rjmp L14
	.dbline 60
;    	_NOP();
	nop
	.dbline 61
;    	return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
	in R16,0x1
	andi R16,248
	.dbline -2
L13:
	.dbline 0 ; func end
	ret
	.dbsym r data 16 c
	.dbend
	.dbfunc e i2c_read _i2c_read fc
	.even
_i2c_read::
	.dbline -1
	.dbline 67
; }
; 
; 
; //从器件读出一个字节
; uint8 i2c_read(void)
; {
	.dbline 68
;    	TWCR = (1<<TWINT)|(1<<TWEN); 
	ldi R24,132
	out 0x36,R24
	.dbline 69
; 	Twi_NoAcK();
	.dbline 69
	in R24,0x36
	andi R24,15
	ori R24,128
	out 0x36,R24
	.dbline 69
	.dbline 69
L18:
	.dbline 70
L19:
	.dbline 70
; 	while (!(TWCR & (1<<TWINT)));
	in R2,0x36
	sbrs R2,7
	rjmp L18
	.dbline 71
;    	return(TWDR);
	in R16,0x3
	.dbline -2
L17:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e i2c_stop _i2c_stop fV
	.even
_i2c_stop::
	.dbline -1
	.dbline 76
; }
; 
; //总线上起动停止条件 
; void i2c_stop(void) 
; { 
	.dbline 77
;    TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); 
	ldi R24,148
	out 0x36,R24
	.dbline -2
L21:
	.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 82
; }
; 
; //操作步骤: 启动,发送地址,发送数据,关闭总线
; void i2c_maste_transt(uint8 addr, uint8 data)
; {
	.dbline 83
;  i2c_start();
	xcall _i2c_start
	.dbline 85
;  
;  if(i2c_write_addr(addr, 0)==TW_MT_SLA_ACK) //发送地址成功并收到ACK
	clr R18
	mov R16,R22
	xcall _i2c_write_addr
	cpi R16,24
	brne L23
	.dbline 86
;  {
	.dbline 87
;   i2c_write_data(data);
	mov R16,R20
	xcall _i2c_write_data
	.dbline 88
;  }
L23:
	.dbline 89
;  i2c_stop();
	xcall _i2c_stop
	.dbline -2
L22:
	xcall pop_gset2
	.dbline 0 ; func end
	ret
	.dbsym r data 20 c
	.dbsym r addr 22 c
	.dbend
	.dbfunc e i2c_maste_read _i2c_maste_read fc
;            tmp -> R20
;           addr -> R22
	.even
_i2c_maste_read::
	xcall push_gset2
	mov R22,R16
	.dbline -1
	.dbline 93
; }
; //操作步骤,启动,发送地址,读数据,关闭总线
; uint8 i2c_maste_read(uint8 addr)
; {
	.dbline 94
;   uint8 tmp=0; 
	clr R20
	.dbline 95
;   i2c_start();
	xcall _i2c_start
	.dbline 96
;   if(i2c_write_addr(addr, 1)==TW_MR_SLA_ACK) //发送地址成功并收到ACK
	ldi R18,1
	mov R16,R22
	xcall _i2c_write_addr
	cpi R16,64
	brne L26
	.dbline 97
;   {
	.dbline 98
;    tmp=i2c_read();
	xcall _i2c_read
	mov R20,R16
	.dbline 99
;   }
L26:
	.dbline 100
;   i2c_stop();
	xcall _i2c_stop
	.dbline 101
;   return tmp;
	mov R16,R20
	.dbline -2
L25:
	xcall pop_gset2
	.dbline 0 ; func end
	ret
	.dbsym r tmp 20 c
	.dbsym r addr 22 c
	.dbend

⌨️ 快捷键说明

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