📄 twi.lis
字号:
.module twi.c
.area vector(rom, abs)
.org 34
0022 D6C0 rjmp _twi_isr
.area text(rom, con, rel)
0000 .dbfile E:\iccavr\无线+I2C\test1--mt\twi.c
0000 .dbfunc e StopDelay _StopDelay fV
0000 ; i -> R16,R17
.even
0000 _StopDelay::
0000 .dbline -1
0000 .dbline 40
0000 ;
0000 ; /*函数的使用说明:
0000 ; 1.该twi模块包含四种工作模式,主发,主收,从收,从发,其中主发由
0000 ; twiWriteByte(从机地址,要发送的数据)实现,主收由twiReadByte(从机地址)实现,从机
0000 ; 的发送与接收均通过中断实现
0000 ; 2.在从机模式下,需调用twi_init()来使能并初始化twi总线
0000 ; 3.在主机模式下,调用twiWriteByte(从机地址,要发送的数据)向指定的从机写入数据,
0000 ; 调用twiReadByte(从机地址)从指定的从机读取数据,然后可通过查询错误状态error_state
0000 ; 的值决定下一步如何操作。
0000 ; */
0000 ;
0000 ; //************************* 头文件 ******************************************
0000 ; #include "twi.h"
0000 ;
0000 ; //TWI同程序的接口参数
0000 ; //receive_data,error_state不用设置
0000 ; extern char receive_data; // 接收到的数据
0000 ; extern char error_state; // twi错误状态
0000 ; //以下三个参数根据需求进行设置
0000 ; extern char slave_address; // 设置从机地址,Bits 7..1:存放从机地址,Bit 0:最低位为广播识别使能位
0000 ; extern char bit_race; // 设置主机模式的比特率,SCL=CPU频率/(16+2*(TWBR)*4TWPS),TWPS在4的指数位置
0000 ; extern char send_data; // 从机发送模式下从机向主机发送的数据
0000 ;
0000 ; //*************************** twi错误状态说明*********************************
0000 ; // 0:twi传送无错误
0000 ; // 1:在主发模式下,SLA+W已发送,返回NOT ACK
0000 ; // 2:在主发模式下,DATA已发送,返回NOT ACK
0000 ; // 3:在主发模式下,SLA+W或者数据的仲裁失败
0000 ; // 4:在主收模式下,SLA+R或者数据的仲裁失败
0000 ; // 5:在主收模式下,SLA+R已发送,返回NOT ACK
0000 ; // 6:在主发模式下,START信号发送不成功
0000 ; // 7:在主收模式下,START信号发送不成功
0000 ; // 8:在主收模式下,数据接受完成
0000 ; // 9:在主收模式下,数据接受不成功
0000 ; //*****************************************************************************
0000 ;
0000 ; //*************************** twi stop 信号延时时间 ****************************
0000 ; //******************************************************************************
0000 ; void StopDelay(void)
0000 ; {
0000 .dbline 42
0000 0027 clr R16
0002 1127 clr R17
0004 02C0 rjmp L5
0006 L2:
0006 .dbline 42
0006 L3:
0006 .dbline 42
0006 0F5F subi R16,255 ; offset = 1
0008 1F4F sbci R17,255
000A L5:
000A .dbline 42
000A ; unsigned int i;
000A ; for(i = 0;i < 20;i ++);
000A 0431 cpi R16,20
000C E0E0 ldi R30,0
000E 1E07 cpc R17,R30
0010 D0F3 brlo L2
0012 .dbline -2
0012 .dbline 43
0012 ; }
0012 L1:
0012 .dbline 0 ; func end
0012 0895 ret
0014 .dbsym r i 16 i
0014 .dbend
0014 .dbfunc e start _start fV
.even
0014 _start::
0014 .dbline -1
0014 .dbline 47
0014 ; //******************************* twi 启动总线*********************************
0014 ; //******************************************************************************
0014 ; void start(void)
0014 ; {
0014 .dbline 48
0014 ; TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); //发出start信号
0014 84EA ldi R24,164
0016 86BF out 0x36,R24
0018 .dbline 49
0018 ; _NOP();
0018 0000 nop
001A .dbline 50
001A ; _NOP();
001A 0000 nop
001C .dbline -2
001C .dbline 51
001C ; }
001C L6:
001C .dbline 0 ; func end
001C 0895 ret
001E .dbend
001E .dbfunc e stop _stop fV
.even
001E _stop::
001E .dbline -1
001E .dbline 55
001E ; //************************** twi 释放总线************************************
001E ; //***************************************************************************
001E ; void stop(void)
001E ; {
001E .dbline 56
001E ; TWCR = (1 << TWINT) |(1 << TWEN)|(1 << TWSTO); //发出stop信号
001E 84E9 ldi R24,148
0020 86BF out 0x36,R24
0022 .dbline 57
0022 ; StopDelay(); //等待总线恢复
0022 EEDF rcall _StopDelay
0024 .dbline 58
0024 ; TWCR= 0x45;
0024 85E4 ldi R24,69
0026 86BF out 0x36,R24
0028 .dbline -2
0028 .dbline 59
0028 ; }
0028 L7:
0028 .dbline 0 ; func end
0028 0895 ret
002A .dbend
002A .dbfunc e twi_init _twi_init fV
.even
002A _twi_init::
002A .dbline -1
002A .dbline 71
002A ; //****************************** twi 初始化*************************************
002A ; // TWCR: 控制寄存器,用来控制TWI操作,说明如下:
002A ; // Bit 7-TWINT:中断标志位,Bit 6-TWEA:使能应答位,Bit 5-TWSTA:START状态位
002A ; // Bit 4-TWSTO:STOP状态位,Bit 3-TWWC: 写冲突标志,Bit 2-TWEN:TWI使能位
002A ; // Bit 1-RES:保留,Bit 0-TWIE:中断使能
002A ; // TWSR: 状态寄存器,Bits 7..3:表示了TWI总线的当前状态,读取时需屏蔽低三位的值,Bits 1..0-TWPS:TWI预分频位
002A ; // TWBR: 比特率寄存器,用来设置TWI的工作频率,计算公式为:SCL=CPU频率/(16+2*(TWBR)*4TWPS),TWPS在4的指数位置
002A ; // TWAR: 从机地址寄存器,Bits 7..1:存放从机地址,Bit 0:最低位为广播识别使能位
002A ; // TWDR: 数据寄存器,用来存放接收或要发送的地址和数据
002A ; //******************************************************************************
002A ; void twi_init(void)
002A ; {
002A .dbline 72
002A ; TWCR= 0x00; //disable twi
002A 2224 clr R2
002C 26BE out 0x36,R2
002E .dbline 73
002E ; TWBR= bit_race; //set bit rate
002E 20900000 lds R2,_bit_race
0032 20B8 out 0x0,R2
0034 .dbline 74
0034 ; TWSR= 0x00; //set prescale为1
0034 2224 clr R2
0036 21B8 out 0x1,R2
0038 .dbline 75
0038 ; TWAR= slave_address; //set slave address
0038 20900000 lds R2,_slave_address
003C 22B8 out 0x2,R2
003E .dbline 76
003E ; TWCR= 0x45; //enable twi
003E 85E4 ldi R24,69
0040 86BF out 0x36,R24
0042 .dbline -2
0042 .dbline 77
0042 ; }
0042 L8:
0042 .dbline 0 ; func end
0042 0895 ret
0044 .dbend
0044 .dbfunc e checkstate _checkstate fV
0044 ; TWSR_state -> R16
.even
0044 _checkstate::
0044 .dbline -1
0044 .dbline 81
0044 ; //************************** 检测发送时的状态码 ****************************
0044 ; //**************************************************************************
0044 ; void checkstate(void)
0044 ; {
0044 .dbline 83
0044 ; unsigned char TWSR_state;
0044 ; TWSR_state = TWSR & 0xf8; //屏蔽第三位读取状态
0044 01B1 in R16,0x1
0046 087F andi R16,248
0048 .dbline 84
0048 ; switch(TWSR_state)
0048 1127 clr R17
004A 0032 cpi R16,32
004C E0E0 ldi R30,0
004E 1E07 cpc R17,R30
0050 69F1 breq L15
0052 80E2 ldi R24,32
0054 90E0 ldi R25,0
0056 8017 cp R24,R16
0058 9107 cpc R25,R17
005A 6CF0 brlt L20
005C L19:
005C 0830 cpi R16,8
005E E0E0 ldi R30,0
0060 1E07 cpc R17,R30
0062 E1F0 breq L13
0064 0830 cpi R16,8
0066 E0E0 ldi R30,0
0068 1E07 cpc R17,R30
006A 7CF1 brlt L11
006C L21:
006C 0831 cpi R16,24
006E E0E0 ldi R30,0
0070 1E07 cpc R17,R30
0072 C1F0 breq L14
0074 2AC0 rjmp L11
0076 L20:
0076 0033 cpi R16,48
0078 E0E0 ldi R30,0
007A 1E07 cpc R17,R30
007C F9F0 breq L17
007E 80E3 ldi R24,48
0080 90E0 ldi R25,0
0082 8017 cp R24,R16
0084 9107 cpc R25,R17
0086 2CF0 brlt L23
0088 L22:
0088 0832 cpi R16,40
008A E0E0 ldi R30,0
008C 1E07 cpc R17,R30
008E 91F0 breq L16
0090 1CC0 rjmp L11
0092 L23:
0092 0833 cpi R16,56
0094 E0E0 ldi R30,0
0096 1E07 cpc R17,R30
0098 A9F0 breq L18
009A 17C0 rjmp L11
009C X0:
009C .dbline 85
009C ; {
009C L13:
009C .dbline 86
009C ; case 0x08:error_state=0;break; // START已发送
009C 2224 clr R2
009E 20920000 sts _error_state,R2
00A2 .dbline 86
00A2 13C0 rjmp L11
00A4 L14:
00A4 .dbline 87
00A4 ; case 0x18:error_state=0;break; // SLA+W已发送,接收到ACK
00A4 2224 clr R2
00A6 20920000 sts _error_state,R2
00AA .dbline 87
00AA 0FC0 rjmp L11
00AC L15:
00AC .dbline 88
00AC ; case 0x20:error_state=1;break; // SLA+W已发送,接收到NOT ACK
00AC 81E0 ldi R24,1
00AE 80930000 sts _error_state,R24
00B2 .dbline 88
00B2 0BC0 rjmp L11
00B4 L16:
00B4 .dbline 89
00B4 ; case 0x28:error_state=0;break; // 数据已发送,接收到ACK
00B4 2224 clr R2
00B6 20920000 sts _error_state,R2
00BA .dbline 89
00BA 07C0 rjmp L11
00BC L17:
00BC .dbline 90
00BC ; case 0x30:error_state=2;break; // 数据已发送,接收到NOT ACK
00BC 82E0 ldi R24,2
00BE 80930000 sts _error_state,R24
00C2 .dbline 90
00C2 03C0 rjmp L11
00C4 L18:
00C4 .dbline 91
00C4 ; case 0x38:error_state=3;break; // SLA+W或数据的仲裁失败
00C4 83E0 ldi R24,3
00C6 80930000 sts _error_state,R24
00CA .dbline 91
00CA .dbline 92
00CA ; default: break;
00CA L11:
00CA .dbline 94
00CA ; }
00CA ; TWCR=0x45;
00CA 85E4 ldi R24,69
00CC 86BF out 0x36,R24
00CE .dbline -2
00CE .dbline 95
00CE ; }
00CE L9:
00CE .dbline 0 ; func end
00CE 0895 ret
00D0 .dbsym r TWSR_state 16 c
00D0 .dbend
00D0 .dbfunc e twiWriteByte _twiWriteByte fV
00D0 ; i -> R12
00D0 ; TWCR_state -> R20
00D0 ; data -> R22
00D0 ; WriteAddress -> R10
.even
00D0 _twiWriteByte::
00D0 00D0 rcall push_gset4
00D2 622F mov R22,R18
00D4 A02E mov R10,R16
00D6 .dbline -1
00D6 .dbline 102
00D6 ; //********** twi主机发送,向地址为WriteAddress的从机发送1个字节数据************
00D6 ; // 入口参数1:WriteAddress:从机地址
00D6 ; // TWDR中存放的高七位为地址,最低位表示读写控制,0为写,1为读
00D6 ; // 入口参数2:data,向从机写的数据
00D6 ; //******************************************************************************
00D6 ; void twiWriteByte(unsigned char WriteAddress,char data)
00D6 ; {
00D6 .dbline 104
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -