📄 twi.lis
字号:
.module twi.c
.area data(ram, con, rel)
0000 _ORGDATA::
0000 .blkb 2
.area idata
0000 AAA5 .byte 170,165
.area data(ram, con, rel)
0002 .blkb 2
.area idata
0002 555A .byte 'U,'Z
.area data(ram, con, rel)
0004 .blkb 2
.area idata
0004 0102 .byte 1,2
.area data(ram, con, rel)
0006 .blkb 2
.area idata
0006 0304 .byte 3,4
.area data(ram, con, rel)
0008 .dbfile D:\myavrproject\icc\twi\twi.c
0008 .dbsym e ORGDATA _ORGDATA A[8:8]c
.area text(rom, con, rel)
0000 .dbfile D:\myavrproject\icc\twi\twi.c
0000 .dbfunc e twi_init _twi_init fV
.even
0000 _twi_init::
0000 .dbline -1
0000 .dbline 22
0000 ; //ICC-AVR application builder : 2007-1-9 16:35:49
0000 ; // Target : M8
0000 ; // Crystal: 8.0000Mhz
0000 ;
0000 ; #include <iom8v.h>
0000 ; #include <macros.h>
0000 ;
0000 ; #include "twi.h"
0000 ;
0000 ;
0000 ; //TWI的数据结构变量
0000 ; struct str_TWI strTWI;
0000 ; //定义全局变量
0000 ; unsigned char ORGDATA[8]={0xAA,0xA5,0x55,0x5A,0x01,0x02,0x03,0x04}; //原始数据
0000 ; //unsigned char CMPDATA[8]; //比较数据
0000 ;
0000 ;
0000 ; //TWI initialize
0000 ; // bit rate:72
0000 ; //50KHZ
0000 ; void twi_init(void)
0000 ; {
0000 .dbline 23
0000 ; TWCR= 0X00; //disable twi
0000 2224 clr R2
0002 26BE out 0x36,R2
0004 .dbline 24
0004 ; TWBR= 0x48; //set bit rate
0004 88E4 ldi R24,72
0006 80B9 out 0x0,R24
0008 .dbline 25
0008 ; TWSR= 0x00; //set prescale
0008 21B8 out 0x1,R2
000A .dbline 26
000A ; TWAR= 0x21; //set slave address
000A 81E2 ldi R24,33
000C 82B9 out 0x2,R24
000E .dbline 28
000E ; //TWAR= 0x31; //set slave address
000E ; TWCR= 0x45; //enable twi
000E 85E4 ldi R24,69
0010 86BF out 0x36,R24
0012 .dbline -2
0012 L1:
0012 .dbline 0 ; func end
0012 0895 ret
0014 .dbend
0014 .dbfunc e TWI_RW _TWI_RW fc
0014 ; i -> <dead>
0014 ; len -> y+0
0014 ; ptr -> R18,R19
0014 ; sla_rw -> R16
.even
0014 _TWI_RW::
0014 .dbline -1
0014 .dbline 34
0014 ; }
0014 ;
0014 ; //
0014 ;
0014 ; unsigned char TWI_RW(unsigned char sla_rw,unsigned char *ptr,unsigned char len)
0014 ; {
0014 .dbline 36
0014 ; unsigned char i;
0014 ; if (strTWI.STATUS==TW_BUSY)
0014 20900000 lds R2,_strTWI
0018 2220 tst R2
001A 11F4 brne L3
001C .dbline 37
001C ; {
001C .dbline 39
001C ; //TWI忙,不能进行操作
001C ; return OP_BUSY;
001C 0027 clr R16
001E 14C0 rjmp L2
0020 L3:
0020 .dbline 41
0020 ; }
0020 ; strTWI.STATUS=TW_BUSY;
0020 2224 clr R2
0022 20920000 sts _strTWI,R2
0026 .dbline 42
0026 ; strTWI.SLA=sla_rw;
0026 00930100 sts _strTWI+1,R16
002A .dbline 43
002A ; strTWI.DATALEN=len;
002A 0880 ldd R0,y+0
002C 00920400 sts _strTWI+4,R0
0030 .dbline 44
0030 ; strTWI.pBUF=ptr;
0030 30930300 sts _strTWI+2+1,R19
0034 20930200 sts _strTWI+2,R18
0038 .dbline 45
0038 ; strTWI.STATE=ST_START;
0038 81E0 ldi R24,1
003A 80930500 sts _strTWI+5,R24
003E .dbline 46
003E ; strTWI.FAILCNT=0;
003E 20920600 sts _strTWI+6,R2
0042 .dbline 47
0042 ; TWCR=(1<<TWSTA)|TW_ACT; //启动start信号
0042 85EA ldi R24,165
0044 86BF out 0x36,R24
0046 .dbline 48
0046 ; return OP_RUN;
0046 01E0 ldi R16,1
0048 .dbline -2
0048 L2:
0048 .dbline 0 ; func end
0048 0895 ret
004A .dbsym l i 1 c
004A .dbsym l len 0 c
004A .dbsym r ptr 18 pc
004A .dbsym r sla_rw 16 c
004A .dbend
.area vector(rom, abs)
.org 34
0022 25C0 rjmp _twi_isr
.area text(rom, con, rel)
004A .dbfile D:\myavrproject\icc\twi\twi.c
004A .dbfunc e twi_isr _twi_isr fV
004A ; action -> R10
004A ; state -> R20
004A ; status -> R22
.even
004A _twi_isr::
004A 00D0 rcall push_lset
004C 00D0 rcall push_gset4
004E .dbline -1
004E .dbline 53
004E ; }
004E ;
004E ; #pragma interrupt_handler twi_isr:18
004E ; void twi_isr(void)
004E ; {
004E .dbline 59
004E ; //twi event
004E ; //根据strTWI.SLA的最低位决定
004E ; //bit0=1 TW_READ 读
004E ; //bit0=0 TW_WRITE 写
004E ; unsigned char action,state,status;
004E ; action=strTWI.SLA&TW_READ; //取操作模式
004E 80910100 lds R24,_strTWI+1
0052 8170 andi R24,1
0054 A82E mov R10,R24
0056 .dbline 60
0056 ; state=strTWI.STATE;
0056 40910500 lds R20,_strTWI+5
005A .dbline 61
005A ; status=TWSR&0xF8; //屏蔽预分频位
005A 61B1 in R22,0x1
005C 687F andi R22,248
005E .dbline 62
005E ; putchar(0xdd);
005E 0DED ldi R16,221
0060 10E0 ldi R17,0
0062 00D0 rcall _putchar
0064 .dbline 63
0064 ; if ((status>=0x60)&&(status!=0x00))
0064 6036 cpi R22,96
0066 28F0 brlo L13
0068 6623 tst R22
006A 19F0 breq L13
006C .dbline 64
006C ; {
006C .dbline 65
006C ; switch(state)
006C C42E mov R12,R20
006E DD24 clr R13
0070 DCC0 rjmp L14
0072 X0:
0072 .dbline 66
0072 ; {
0072 .dbline 70
0072 ; //case ST_START: //START状态检查
0072 ;
0072 ; }
0072 ; }
0072 L13:
0072 .dbline 71
0072 ; else if((status<0x60)&&(status!=0x00))
0072 6036 cpi R22,96
0074 08F0 brlo X2
0076 D9C0 rjmp L10
0078 X2:
0078 6623 tst R22
007A 09F4 brne X3
007C D6C0 rjmp L10
007E X3:
007E .dbline 72
007E ; {
007E .dbline 73
007E ; switch(state)
007E C42E mov R12,R20
0080 DD24 clr R13
0082 C601 movw R24,R12
0084 8130 cpi R24,1
0086 E0E0 ldi R30,0
0088 9E07 cpc R25,R30
008A E9F0 breq L23
008C 8230 cpi R24,2
008E E0E0 ldi R30,0
0090 9E07 cpc R25,R30
0092 21F1 breq L27
0094 8330 cpi R24,3
0096 E0E0 ldi R30,0
0098 9E07 cpc R25,R30
009A 49F1 breq L30
009C 8430 cpi R24,4
009E E0E0 ldi R30,0
00A0 9E07 cpc R25,R30
00A2 09F4 brne X4
00A4 41C0 rjmp L37
00A6 X4:
00A6 8530 cpi R24,5
00A8 E0E0 ldi R30,0
00AA 9E07 cpc R25,R30
00AC 09F4 brne X5
00AE 46C0 rjmp L41
00B0 X5:
00B0 8630 cpi R24,6
00B2 E0E0 ldi R30,0
00B4 9E07 cpc R25,R30
00B6 09F4 brne X6
00B8 53C0 rjmp L47
00BA X6:
00BA 8730 cpi R24,7
00BC E0E0 ldi R30,0
00BE 9E07 cpc R25,R30
00C0 09F4 brne X7
00C2 7DC0 rjmp L57
00C4 X7:
00C4 9DC0 rjmp L20
00C6 X1:
00C6 .dbline 74
00C6 ; {
00C6 L23:
00C6 .dbline 76
00C6 ; case ST_START: //START状态检查
00C6 ; if(status==TW_START)
00C6 6830 cpi R22,8
00C8 39F4 brne L24
00CA .dbline 77
00CA ; {//发送start信号成功
00CA .dbline 78
00CA ; TWDR=strTWI.SLA&0xFE; //发送器件地址写SLAW
00CA 80910100 lds R24,_strTWI+1
00CE 8E7F andi R24,254
00D0 83B9 out 0x3,R24
00D2 .dbline 79
00D2 ; TWCR=TW_ACT; //触发下一步动作,同时清start发送标志
00D2 85E8 ldi R24,133
00D4 86BF out 0x36,R24
00D6 .dbline 80
00D6 ; }
00D6 95C0 rjmp L21
00D8 L24:
00D8 .dbline 82
00D8 ; else
00D8 ; {//发送start信号出错
00D8 .dbline 83
00D8 ; state=ST_FAIL;
00D8 4427 clr R20
00DA .dbline 84
00DA ; }
00DA .dbline 85
00DA ; break;
00DA 93C0 rjmp L21
00DC L27:
00DC .dbline 87
00DC ; case ST_SLAW: //SLAW状态检查
00DC ; if(status==TW_MT_SLA_ACK)
00DC 6831 cpi R22,24
00DE 29F4 brne L28
00E0 .dbline 88
00E0 ; {//发送器件地址成功
00E0 .dbline 89
00E0 ; TWDR=0xab;
00E0 8BEA ldi R24,171
00E2 83B9 out 0x3,R24
00E4 .dbline 90
00E4 ; TWCR=TW_ACT; //触发下一步动作
00E4 85E8 ldi R24,133
00E6 86BF out 0x36,R24
00E8 .dbline 91
00E8 ; }
00E8 8CC0 rjmp L21
00EA L28:
00EA .dbline 93
00EA ; else
00EA ; {//发送器件地址出错
00EA .dbline 94
00EA ; state=ST_FAIL;
00EA 4427 clr R20
00EC .dbline 95
00EC ; }
00EC .dbline 96
00EC ; break;
00EC 8AC0 rjmp L21
00EE L30:
00EE .dbline 98
00EE ; case ST_WADDR: //ADDR状态检查
00EE ; if(status==TW_MT_DATA_ACK)
00EE 6832 cpi R22,40
00F0 C9F4 brne L31
00F2 .dbline 99
00F2 ; {//发送eeprom地址成功
00F2 .dbline 100
00F2 ; if (action==TW_READ)
00F2 8A2D mov R24,R10
00F4 8130 cpi R24,1
00F6 19F4 brne L33
00F8 .dbline 101
00F8 ; {//读操作模式
00F8 .dbline 102
00F8 ; TWCR=(1<<TWSTA)|TW_ACT; //发送restart信号,下一步将跳到RESTART分支
00F8 85EA ldi R24,165
00FA 86BF out 0x36,R24
00FC .dbline 103
00FC ; }
00FC 82C0 rjmp L21
00FE L33:
00FE .dbline 105
00FE ; else
00FE ; {//写操作模式
00FE .dbline 106
00FE ; TWDR=*strTWI.pBUF++; //写第一个字节
00FE E0910200 lds R30,_strTWI+2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -