📄 013.lst
字号:
__text_start:
__start:
002A E5CF LDI R28,0x5F
002B E0D4 LDI R29,4
002C BFCD OUT 0x3D,R28
002D BFDE OUT 0x3E,R29
002E 51C0 SUBI R28,0x10
002F 40D0 SBCI R29,0
0030 EA0A LDI R16,0xAA
0031 8308 STD Y+0,R16
0032 2400 CLR R0
0033 E6E0 LDI R30,0x60
0034 E0F0 LDI R31,0
0035 E010 LDI R17,0
0036 36E0 CPI R30,0x60
0037 07F1 CPC R31,R17
0038 F011 BEQ 0x003B
0039 9201 ST R0,Z+
003A CFFB RJMP 0x0036
003B 8300 STD Z+0,R16
003C E5E4 LDI R30,0x54
003D E0F0 LDI R31,0
003E E6A0 LDI R26,0x60
003F E0B0 LDI R27,0
0040 E010 LDI R17,0
0041 35E4 CPI R30,0x54
0042 07F1 CPC R31,R17
0043 F021 BEQ 0x0048
0044 95C8 LPM
0045 9631 ADIW R30,1
0046 920D ST R0,X+
0047 CFF9 RJMP 0x0041
0048 940E012C CALL _main
_exit:
004A CFFF RJMP _exit
_error:
type --> R16
004B 940E0155 CALL push_gset1
FILE: E:\ICCAVR\project\AVRMEG~2\icc\013-IIC-LED\twi.c
(0001) /*
(0002) I2C总线/TWI操作模块
(0003) 1、读取和写入函数
(0004) 2、地址有效范围255
(0005) 3、数据长度为单字节
(0006) 4、函数采用查询方式
(0007) 5、可直接嵌入到项目中使用
(0008) 6、晶振频率:1M
(0009) 7、总线速度:50K
(0010)
(0011) AVR_AFA
(0012) www.iccavr.com
(0013) */
(0014)
(0015) #include "iom16v.h"
(0016)
(0017) /*I2C总线主机模式错误处理*/
(0018) void error(unsigned char type) {
(0019)
(0020) switch (type & 0xF8) {
004D 2F40 MOV R20,R16
004E 2755 CLR R21
004F 7F48 ANDI R20,0xF8
0050 7050 ANDI R21,0
0051 3340 CPI R20,0x30
0052 E0E0 LDI R30,0
0053 075E CPC R21,R30
0054 F0D1 BEQ 0x006F
0055 E380 LDI R24,0x30
0056 E090 LDI R25,0
0057 1784 CP R24,R20
0058 0795 CPC R25,R21
0059 F02C BLT 0x005F
005A 3240 CPI R20,0x20
005B E0E0 LDI R30,0
005C 075E CPC R21,R30
005D F071 BEQ 0x006C
005E C015 RJMP 0x0074
005F 3348 CPI R20,0x38
0060 E0E0 LDI R30,0
0061 075E CPC R21,R30
0062 F089 BEQ 0x0074
0063 3348 CPI R20,0x38
0064 E0E0 LDI R30,0
0065 075E CPC R21,R30
0066 F06C BLT 0x0074
0067 3448 CPI R20,0x48
0068 E0E0 LDI R30,0
0069 075E CPC R21,R30
006A F039 BEQ 0x0072
006B C008 RJMP 0x0074
(0021) case 0x20: /*址址写失败*/
(0022) /*stop 停止*/
(0023) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
006C E984 LDI R24,0x94
006D BF86 OUT 0x36,R24
(0024) break;
006E C005 RJMP 0x0074
(0025) case 0x30: /*数据写失败*/
(0026) /*stop 停止*/
(0027) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
006F E984 LDI R24,0x94
0070 BF86 OUT 0x36,R24
(0028) break;
0071 C002 RJMP 0x0074
(0029) case 0x38: /*仲裁失败*/
(0030) break;
(0031) case 0x48: /*址址读失败*/
(0032) /*stop 停止*/
(0033) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
0072 E984 LDI R24,0x94
0073 BF86 OUT 0x36,R24
(0034) break;
0074 940E0158 CALL pop_gset1
0076 9508 RET
_twi_write:
dd --> R20
addr --> R22
0077 940E0153 CALL push_gset2
0079 2F42 MOV R20,R18
007A 2F60 MOV R22,R16
(0035) }
(0036) }
(0037)
(0038) /*I2C总线单字节写入*/
(0039) unsigned char twi_write(unsigned char addr, unsigned char dd) {
(0040)
(0041) TWBR = 2;
007B E082 LDI R24,2
007C B980 OUT 0x00,R24
(0042)
(0043) /*start 启动*/
(0044) TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
007D EA84 LDI R24,0xA4
007E BF86 OUT 0x36,R24
(0045) while (!(TWCR & (1 << TWINT)));
007F B626 IN R2,0x36
0080 FE27 SBRS R2,7
0081 CFFD RJMP 0x007F
(0046) if ((TWSR & 0xF8) != 0x08) {
0082 B181 IN R24,0x01
0083 7F88 ANDI R24,0xF8
0084 3088 CPI R24,0x8
0085 F021 BEQ 0x008A
(0047) error(TWSR);
0086 B101 IN R16,0x01
0087 DFC3 RCALL _error
(0048) return 0;
0088 2700 CLR R16
0089 C02E RJMP 0x00B8
(0049) }
(0050)
(0051) /*SLA_W 芯片地址*/
(0052) TWDR = 0xA0;
008A EA80 LDI R24,0xA0
008B B983 OUT 0x03,R24
(0053) TWCR = (1 << TWINT) | (1 << TWEN);
008C E884 LDI R24,0x84
008D BF86 OUT 0x36,R24
(0054) while (!(TWCR & (1 << TWINT)));
008E B626 IN R2,0x36
008F FE27 SBRS R2,7
0090 CFFD RJMP 0x008E
(0055) if ((TWSR & 0xF8) != 0x18) {
0091 B181 IN R24,0x01
0092 7F88 ANDI R24,0xF8
0093 3188 CPI R24,0x18
0094 F021 BEQ 0x0099
(0056) error(TWSR);
0095 B101 IN R16,0x01
0096 DFB4 RCALL _error
(0057) return 0;
0097 2700 CLR R16
0098 C01F RJMP 0x00B8
(0058) }
(0059)
(0060) /*addr 操作地址*/
(0061) TWDR = addr;
0099 B963 OUT 0x03,R22
(0062) TWCR = (1 << TWINT) | (1 << TWEN);
009A E884 LDI R24,0x84
009B BF86 OUT 0x36,R24
(0063) while (!(TWCR & (1 << TWINT)));
009C B626 IN R2,0x36
009D FE27 SBRS R2,7
009E CFFD RJMP 0x009C
(0064) if ((TWSR & 0xF8) != 0x28) {
009F B181 IN R24,0x01
00A0 7F88 ANDI R24,0xF8
00A1 3288 CPI R24,0x28
00A2 F021 BEQ 0x00A7
(0065) error(TWSR);
00A3 B101 IN R16,0x01
00A4 DFA6 RCALL _error
(0066) return 0;
00A5 2700 CLR R16
00A6 C011 RJMP 0x00B8
(0067) }
(0068)
(0069) /*dd 写入数据*/
(0070) TWDR = dd;
00A7 B943 OUT 0x03,R20
(0071) TWCR = (1 << TWINT) | (1 << TWEN);
00A8 E884 LDI R24,0x84
00A9 BF86 OUT 0x36,R24
(0072) while (!(TWCR & (1 << TWINT)));
00AA B626 IN R2,0x36
00AB FE27 SBRS R2,7
00AC CFFD RJMP 0x00AA
(0073) if ((TWSR & 0xF8) != 0x28) {
00AD B181 IN R24,0x01
00AE 7F88 ANDI R24,0xF8
00AF 3288 CPI R24,0x28
00B0 F021 BEQ 0x00B5
(0074) error(TWSR);
00B1 B101 IN R16,0x01
00B2 DF98 RCALL _error
(0075) return 0;
00B3 2700 CLR R16
00B4 C003 RJMP 0x00B8
(0076) }
(0077)
(0078) /*stop 停止*/
(0079) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
00B5 E984 LDI R24,0x94
00B6 BF86 OUT 0x36,R24
(0080) return 1;
00B7 E001 LDI R16,1
00B8 940E014A CALL pop_gset2
00BA 9508 RET
_twi_read:
dd --> R20
addr --> R22
00BB 940E0153 CALL push_gset2
00BD 01A9 MOVW R20,R18
00BE 2F60 MOV R22,R16
(0081) }
(0082)
(0083) /*I2C总线单字节读取*/
(0084) unsigned char twi_read(unsigned char addr, unsigned char *dd) {
(0085)
(0086) TWBR = 2;
00BF E082 LDI R24,2
00C0 B980 OUT 0x00,R24
(0087)
(0088) /*start 启动*/
(0089) TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
00C1 EA84 LDI R24,0xA4
00C2 BF86 OUT 0x36,R24
(0090) while(!(TWCR&(1<<TWINT)));
00C3 B626 IN R2,0x36
00C4 FE27 SBRS R2,7
00C5 CFFD RJMP 0x00C3
(0091) if ((TWSR & 0xF8) != 0x08) {
00C6 B181 IN R24,0x01
00C7 7F88 ANDI R24,0xF8
00C8 3088 CPI R24,0x8
00C9 F021 BEQ 0x00CE
(0092) error(TWSR);
00CA B101 IN R16,0x01
00CB DF7F RCALL _error
(0093) return 0;
00CC 2700 CLR R16
00CD C04C RJMP 0x011A
(0094) }
(0095)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -