📄 at24c02.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 940E00F8 CALL _main
_exit:
004A CFFF RJMP _exit
_delay_ms:
i --> R20
time --> R16
004B 940E0123 CALL push_gset1
FILE: D:\AVR\我的程序\AT24C02的I2C实验\cfg.h
(0001) /*******************************
(0002) *程序名称:各功能函数
(0003) *设 计:萧联珠
(0004) *日 期:2007-11-20
(0005) ********************************/
(0006) #include <iom16v.h>
(0007)
(0008) /****************************
(0009) I2C 状态定义
(0010) MT 主方式传输 MR 主方式接受
(0011) ***************************/
(0012) #define START 0x08
(0013) #define RE_START 0x10
(0014) #define MT_SLA_ACK 0x18
(0015) #define MT_SLA_NOACK 0x20
(0016) #define MT_DATA_ACK 0x28
(0017) #define MT_DATA_NOACK 0x30
(0018)
(0019) #define MR_SLA_ACK 0x40
(0020) #define MR_SLA_NOACK 0x48
(0021) #define MR_DATA_ACK 0x50
(0022) #define MR_DATA_NOACK 0x58
(0023)
(0024) #define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位
(0025) #define WD_DEVICE_ADDR 0xA0
(0026)
(0027) /*常用TWI操作(主模式写和读)*/
(0028) #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C
(0029) #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C
(0030) #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生
(0031) #define TestAck() (TWSR&0xf8) //观察返回状态
(0032) #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答
(0033) #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答
(0034) #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C
(0035) #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDR
(0036)
(0037) /*延时子程序*/
(0038) void delay_ms(int time)
(0039) {
(0040) int i;
(0041) for(;time>0;time--)
004D C00A RJMP 0x0058
(0042) for(i=0;i<1000;i++);
004E 2744 CLR R20
004F 2755 CLR R21
0050 5F4F SUBI R20,0xFF
0051 4F5F SBCI R21,0xFF
0052 3E48 CPI R20,0xE8
0053 E0E3 LDI R30,3
0054 075E CPC R21,R30
0055 F3D4 BLT 0x0050
0056 5001 SUBI R16,1
0057 4010 SBCI R17,0
0058 2422 CLR R2
0059 2433 CLR R3
005A 1620 CP R2,R16
005B 0631 CPC R3,R17
005C F38C BLT 0x004E
005D 940E0126 CALL pop_gset1
005F 9508 RET
(0043) }
(0044)
(0045) /*串口初始化*/
(0046) void uart_init()
(0047) {
(0048) UCSRA=0x02; //异步正常模式
_uart_init:
0060 E082 LDI R24,2
0061 B98B OUT 0x0B,R24
(0049) UCSRB=0x18; //允许发送接受中断和使能
0062 E188 LDI R24,0x18
0063 B98A OUT 0x0A,R24
(0050) UCSRC=0x06; //8位数据
0064 E086 LDI R24,6
0065 BD80 OUT 0x20,R24
(0051) UBRRH=0x00;
0066 2422 CLR R2
0067 BC20 OUT 0x20,R2
(0052) UBRRL=12; //波特率位9600
0068 E08C LDI R24,0xC
0069 B989 OUT 0x09,R24
006A 9508 RET
_I2C_Write:
RegAddress --> R22
Wdata --> R20
006B 940E0121 CALL push_gset2
006D 2F62 MOV R22,R18
006E 2F40 MOV R20,R16
(0053) }
(0054)
(0055) /*********************************************
(0056) I2C总线写一个字节
(0057) 返回0:写成功
(0058) 返回1:写失败
(0059) **********************************************/
(0060) unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress)
(0061) {
(0062) Start(); //I2C启动
006F EA84 LDI R24,0xA4
0070 BF86 OUT 0x36,R24
(0063) Wait();
0071 B626 IN R2,0x36
0072 FE27 SBRS R2,7
0073 CFFD RJMP 0x0071
(0064) if(TestAck()!=START)
0074 B181 IN R24,0x01
0075 7F88 ANDI R24,0xF8
0076 3088 CPI R24,0x8
0077 F011 BEQ 0x007A
(0065) return 1; //ACK
0078 E001 LDI R16,1
0079 C02B RJMP 0x00A5
(0066)
(0067) Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
007A EA80 LDI R24,0xA0
007B B983 OUT 0x03,R24
007C E884 LDI R24,0x84
007D BF86 OUT 0x36,R24
(0068) Wait();
007E B626 IN R2,0x36
007F FE27 SBRS R2,7
0080 CFFD RJMP 0x007E
(0069) if(TestAck()!=MT_SLA_ACK)
0081 B181 IN R24,0x01
0082 7F88 ANDI R24,0xF8
0083 3188 CPI R24,0x18
0084 F011 BEQ 0x0087
(0070) return 1; //ACK
0085 E001 LDI R16,1
0086 C01E RJMP 0x00A5
(0071)
(0072) Write8Bit(RegAddress); //写器件相应寄存器地址
0087 B963 OUT 0x03,R22
0088 E884 LDI R24,0x84
0089 BF86 OUT 0x36,R24
(0073) Wait();
008A B626 IN R2,0x36
008B FE27 SBRS R2,7
008C CFFD RJMP 0x008A
(0074) if(TestAck()!=MT_DATA_ACK)
008D B181 IN R24,0x01
008E 7F88 ANDI R24,0xF8
008F 3288 CPI R24,0x28
0090 F011 BEQ 0x0093
(0075) return 1; //ACK
0091 E001 LDI R16,1
0092 C012 RJMP 0x00A5
(0076)
(0077) Write8Bit(Wdata); //写数据到器件相应寄存器
0093 B943 OUT 0x03,R20
0094 E884 LDI R24,0x84
0095 BF86 OUT 0x36,R24
(0078) Wait();
0096 B626 IN R2,0x36
0097 FE27 SBRS R2,7
0098 CFFD RJMP 0x0096
(0079) if(TestAck()!=MT_DATA_ACK)
0099 B181 IN R24,0x01
009A 7F88 ANDI R24,0xF8
009B 3288 CPI R24,0x28
009C F011 BEQ 0x009F
(0080) return 1; //ACK
009D E001 LDI R16,1
009E C006 RJMP 0x00A5
(0081)
(0082) Stop(); //I2C停止
009F E984 LDI R24,0x94
00A0 BF86 OUT 0x36,R24
(0083) delay_ms(100); //延时
00A1 E604 LDI R16,0x64
00A2 E010 LDI R17,0
00A3 DFA7 RCALL _delay_ms
(0084) return 0;
00A4 2700 CLR R16
00A5 940E0118 CALL pop_gset2
00A7 9508 RET
_I2C_Read:
temp --> R20
RegAddress --> R16
00A8 940E0123 CALL push_gset1
(0085) }
(0086)
(0087) /*********************************************
(0088) I2C总线读一个字节
(0089) 返回0:读成功
(0090) 返回1:读失败
(0091) **********************************************/
(0092) unsigned char I2C_Read(unsigned RegAddress)
(0093) {
(0094) unsigned char temp;
(0095) Start();//I2C启动
00AA EA84 LDI R24,0xA4
00AB BF86 OUT 0x36,R24
(0096) Wait();
00AC B626 IN R2,0x36
00AD FE27 SBRS R2,7
00AE CFFD RJMP 0x00AC
(0097) if (TestAck()!=START)
00AF B181 IN R24,0x01
00B0 7F88 ANDI R24,0xF8
00B1 3088 CPI R24,0x8
00B2 F011 BEQ 0x00B5
(0098) return 1; //ACK
00B3 E001 LDI R16,1
00B4 C040 RJMP 0x00F5
(0099)
(0100) Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
00B5 EA80 LDI R24,0xA0
00B6 B983 OUT 0x03,R24
00B7 E884 LDI R24,0x84
00B8 BF86 OUT 0x36,R24
(0101) Wait();
00B9 B626 IN R2,0x36
00BA FE27 SBRS R2,7
00BB CFFD RJMP 0x00B9
(0102) if (TestAck()!=MT_SLA_ACK)
00BC B181 IN R24,0x01
00BD 7F88 ANDI R24,0xF8
00BE 3188 CPI R24,0x18
00BF F011 BEQ 0x00C2
(0103) return 1; //ACK
00C0 E001 LDI R16,1
00C1 C033 RJMP 0x00F5
(0104)
(0105) Write8Bit(RegAddress); //写器件相应寄存器地址
00C2 B903 OUT 0x03,R16
00C3 E884 LDI R24,0x84
00C4 BF86 OUT 0x36,R24
(0106) Wait();
00C5 B626 IN R2,0x36
00C6 FE27 SBRS R2,7
00C7 CFFD RJMP 0x00C5
(0107) if (TestAck()!=MT_DATA_ACK)
00C8 B181 IN R24,0x01
00C9 7F88 ANDI R24,0xF8
00CA 3288 CPI R24,0x28
00CB F011 BEQ 0x00CE
(0108) return 1;
00CC E001 LDI R16,1
00CD C027 RJMP 0x00F5
(0109)
(0110) Start(); //I2C重新启动
00CE EA84 LDI R24,0xA4
00CF BF86 OUT 0x36,R24
(0111) Wait();
00D0 B626 IN R2,0x36
00D1 FE27 SBRS R2,7
00D2 CFFD RJMP 0x00D0
(0112) if (TestAck()!=RE_START)
00D3 B181 IN R24,0x01
00D4 7F88 ANDI R24,0xF8
00D5 3180 CPI R24,0x10
00D6 F011 BEQ 0x00D9
(0113) return 1;
00D7 E001 LDI R16,1
00D8 C01C RJMP 0x00F5
(0114)
(0115) Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式
00D9 EA81 LDI R24,0xA1
00DA B983 OUT 0x03,R24
00DB E884 LDI R24,0x84
00DC BF86 OUT 0x36,R24
(0116) Wait();
00DD B626 IN R2,0x36
00DE FE27 SBRS R2,7
00DF CFFD RJMP 0x00DD
(0117) if(TestAck()!=MR_SLA_ACK)
00E0 B181 IN R24,0x01
00E1 7F88 ANDI R24,0xF8
00E2 3480 CPI R24,0x40
00E3 F011 BEQ 0x00E6
(0118) return 1; //ACK
00E4 E001 LDI R16,1
00E5 C00F RJMP 0x00F5
(0119)
(0120) Twi(); //启动主I2C读方式
00E6 E884 LDI R24,0x84
00E7 BF86 OUT 0x36,R24
(0121) Wait();
00E8 B626 IN R2,0x36
00E9 FE27 SBRS R2,7
00EA CFFD RJMP 0x00E8
(0122) if(TestAck()!=MR_DATA_NOACK)
00EB B181 IN R24,0x01
00EC 7F88 ANDI R24,0xF8
00ED 3588 CPI R24,0x58
00EE F011 BEQ 0x00F1
(0123) return 1; //ACK
00EF E001 LDI R16,1
00F0 C004 RJMP 0x00F5
(0124)
(0125) temp=TWDR; //读取I2C接收数据
00F1 B143 IN R20,0x03
(0126) Stop(); //I2C停止
00F2 E984 LDI R24,0x94
00F3 BF86 OUT 0x36,R24
(0127) return temp;
00F4 2F04 MOV R16,R20
00F5 940E0126 CALL pop_gset1
00F7 9508 RET
FILE: D:\AVR\我的程序\AT24C02的I2C实验\main.c
(0001) /***********************************
(0002) *实验目的:熟悉AT24C02编程
(0003) *设 计:萧联珠
(0004) *日 期:2007-11-22
(0005) ************************************/
(0006) #include <iom16v.h>
(0007) #include "cfg.h"
(0008)
(0009) void main()
(0010) {
(0011) unsigned char i;
(0012) uart_init(); /*串口初始化*/
_main:
i --> R20
00F8 DF67 RCALL _uart_init
(0013) for(i=0;i<10;i++)
00F9 2744 CLR R20
00FA C005 RJMP 0x0100
(0014) I2C_Write(i,0x80+i);
00FB 2F24 MOV R18,R20
00FC 5820 SUBI R18,0x80
00FD 2F04 MOV R16,R20
00FE DF6C RCALL _I2C_Write
00FF 9543 INC R20
0100 304A CPI R20,0xA
0101 F3C8 BCS 0x00FB
(0015) delay_ms(1000);
0102 EE08 LDI R16,0xE8
0103 E013 LDI R17,3
0104 DF46 RCALL _delay_ms
0105 C010 RJMP 0x0116
(0016) while(1)
(0017) {
(0018) for(i=0;i<10;i++)
0106 2744 CLR R20
0107 C00C RJMP 0x0114
(0019) {
(0020) while(!(UCSRA&(1<<UDRE))); /*等待接受准备好*/
0108 9B5D SBIS 0x0B,5
0109 CFFE RJMP 0x0108
(0021) delay_ms(10);
010A E00A LDI R16,0xA
010B E010 LDI R17,0
010C DF3E RCALL _delay_ms
(0022) UDR=I2C_Read(0x80+i);
FILE: <library>
010D 2F04 MOV R16,R20
010E 2711 CLR R17
010F 5800 SUBI R16,0x80
0110 4F1F SBCI R17,0xFF
0111 DF96 RCALL _I2C_Read
0112 B90C OUT 0x0C,R16
0113 9543 INC R20
0114 304A CPI R20,0xA
0115 F390 BCS 0x0108
0116 CFEF RJMP 0x0106
0117 9508 RET
pop_gset2:
0118 E0E2 LDI R30,2
0119 940C0127 JMP pop
push_gset5:
011B 92FA ST R15,-Y
011C 92EA ST R14,-Y
push_gset4:
011D 92DA ST R13,-Y
011E 92CA ST R12,-Y
push_gset3:
011F 92BA ST R11,-Y
0120 92AA ST R10,-Y
push_gset2:
0121 937A ST R23,-Y
0122 936A ST R22,-Y
push_gset1:
0123 935A ST R21,-Y
0124 934A ST R20,-Y
0125 9508 RET
pop_gset1:
0126 E0E1 LDI R30,1
pop:
0127 9149 LD R20,Y+
0128 9159 LD R21,Y+
0129 FDE0 SBRC R30,0
012A 9508 RET
012B 9169 LD R22,Y+
012C 9179 LD R23,Y+
012D FDE1 SBRC R30,1
012E 9508 RET
012F 90A9 LD R10,Y+
0130 90B9 LD R11,Y+
0131 FDE2 SBRC R30,2
0132 9508 RET
0133 90C9 LD R12,Y+
0134 90D9 LD R13,Y+
0135 FDE3 SBRC R30,3
0136 9508 RET
0137 90E9 LD R14,Y+
0138 90F9 LD R15,Y+
0139 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -