📄 write_page.lst
字号:
__start:
__text_start:
4E EFCF LDI R28,0xFF
4F E1D0 LDI R29,0x10
50 BFCD OUT 0x3D,R28
51 BFDE OUT 0x3E,R29
52 51CE SUBI R28,0x1E
53 40D0 SBCI R29,0
54 EA0A LDI R16,0xAA
55 8308 STD Y+0,R16
56 2400 CLR R0
57 E0E0 LDI R30,0
58 E0F1 LDI R31,1
59 E011 LDI R17,1
5A 30E0 CPI R30,0
5B 07F1 CPC R31,R17
5C F011 BEQ 0x005F
5D 9201 ST R0,Z+
5E CFFB RJMP 0x005A
5F 8300 STD Z+0,R16
60 E9EC LDI R30,0x9C
61 E0F0 LDI R31,0
62 E0A0 LDI R26,0
63 E0B1 LDI R27,1
64 E010 LDI R17,0
65 E000 LDI R16,0
66 BF0B OUT 0x3B,R16
67 39EC CPI R30,0x9C
68 07F1 CPC R31,R17
69 F021 BEQ 0x006E
6A 95C8 LPM
6B 9631 ADIW R30,1
6C 920D ST R0,X+
6D CFF9 RJMP 0x0067
6E 940E 00F7 CALL _main
_exit:
70 CFFF RJMP _exit
FILE: D:\16实验程序\I2C读写24C04\页写\i2c.h
(0001) ///////////////////////i2c通信子程序///////////////////////
(0002) ///////////////////////////////////////////////////////////
(0003) //初始化
(0004) void i2c_init()
(0005) {
(0006) PORTD&=~0x80;
_i2c_init:
71 9897 CBI 0x12,7
(0007) TWBR=0x01 ; //速率=16M/(16+2*16)=33.3k
72 E081 LDI R24,1
73 B980 OUT 0x00,R24
(0008) TWSR=0x01 ; //分频因子=4
74 B981 OUT 0x01,R24
75 9508 RET
(0009) }
(0010)
(0011)
(0012) //开始信号
(0013) void i2c_start()
(0014) {
(0015) TWCR=0xa4 ;
_i2c_start:
76 EA84 LDI R24,0xA4
77 BF86 OUT 0x36,R24
(0016) while(!(TWCR&0x80));
78 B626 IN R2,0x36
79 FE27 SBRS R2,7
7A CFFD RJMP 0x0078
7B 9508 RET
(0017) }
(0018)
(0019)
(0020) //写数据
(0021) void i2c_wrdata(uchar i2c_data)
(0022) {
(0023) TWDR=(i2c_data);
_i2c_wrdata:
i2c_data --> R16
7C B903 OUT 0x03,R16
(0024) TWCR=0x84 ;
7D E884 LDI R24,0x84
7E BF86 OUT 0x36,R24
(0025) while(!(TWCR&0x80));
7F B626 IN R2,0x36
80 FE27 SBRS R2,7
81 CFFD RJMP 0x007F
82 9508 RET
(0026) }
(0027)
(0028)
(0029) //读数据noack
(0030) uchar i2c_redata()
(0031) {
(0032) uchar i2c_data ;
(0033) TWCR=0x84 ;
_i2c_redata:
i2c_data --> R16
83 E884 LDI R24,0x84
84 BF86 OUT 0x36,R24
(0034) while(!(TWCR&0x80));
85 B626 IN R2,0x36
86 FE27 SBRS R2,7
87 CFFD RJMP 0x0085
(0035) i2c_data=TWDR ;
88 B103 IN R16,0x03
(0036) return(i2c_data);
89 9508 RET
(0037) }
(0038)
(0039) //读数据ack
(0040) uchar i2c_redataack()
(0041) {
(0042) uchar i2c_data ;
(0043) TWCR=0xc4 ;
_i2c_redataack:
i2c_data --> R16
8A EC84 LDI R24,0xC4
8B BF86 OUT 0x36,R24
(0044) while(!(TWCR&0x80));
8C B626 IN R2,0x36
8D FE27 SBRS R2,7
8E CFFD RJMP 0x008C
(0045) i2c_data=TWDR ;
8F B103 IN R16,0x03
(0046) return(i2c_data);
90 9508 RET
(0047) }
(0048)
(0049)
(0050)
(0051) //停止信号
(0052) void i2c_stop()
(0053) {
(0054) TWCR=0x94 ;
_i2c_stop:
91 E984 LDI R24,0x94
92 BF86 OUT 0x36,R24
93 9508 RET
_i2c_wrbyte:
i2c_add --> R12
i2c_data --> R10
94 92AA ST R10,-Y
95 92CA ST R12,-Y
96 2EC2 MOV R12,R18
97 2EA0 MOV R10,R16
(0055) }
(0056)
(0057) //i2c的写字节子程序
(0058) void i2c_wrbyte(uchar i2c_data,uchar i2c_add)
(0059) {
(0060) do
(0061) {
(0062) i2c_start();
98 DFDD RCALL _i2c_start
(0063) i2c_wrdata(0xa0);
99 EA00 LDI R16,0xA0
9A DFE1 RCALL _i2c_wrdata
(0064) }
(0065) while((TWSR&0xf8)!=0x18); //判断总线是否可以操作
9B B181 IN R24,0x01
9C 7F88 ANDI R24,0xF8
9D 3188 CPI R24,0x18
9E F7C9 BNE 0x0098
(0066)
(0067) i2c_wrdata(i2c_add);
9F 2D0C MOV R16,R12
A0 DFDB RCALL _i2c_wrdata
(0068) i2c_wrdata(i2c_data);
A1 2D0A MOV R16,R10
A2 DFD9 RCALL _i2c_wrdata
(0069) i2c_stop();
A3 DFED RCALL _i2c_stop
A4 90C9 LD R12,Y+
A5 90A9 LD R10,Y+
A6 9508 RET
_i2c_wrpage:
i --> R10
i2c_nub --> Y,+4
i2c_add --> R10
i2c_data --> R12
A7 940E 0119 CALL push_xgset003C
A9 2EA2 MOV R10,R18
AA 0168 MOVW R12,R16
(0070) }
(0071)
(0072) //i2c的页写子程序
(0073) //参数1:要写入的数组指针
(0074) //参数2:写入的首地址
(0075) //参数3:数组的单元数
(0076) void i2c_wrpage(uchar *i2c_data,uchar i2c_add,uchar i2c_nub)
(0077) {
(0078) uchar i;
(0079) do
(0080) {
(0081) i2c_start();
AB DFCA RCALL _i2c_start
(0082) i2c_wrdata(0xa0);
AC EA00 LDI R16,0xA0
AD DFCE RCALL _i2c_wrdata
(0083) }
(0084) while((TWSR&0xf8)!=0x18);
AE B181 IN R24,0x01
AF 7F88 ANDI R24,0xF8
B0 3188 CPI R24,0x18
B1 F7C9 BNE 0x00AB
(0085) //判断总线是否可以操作
(0086) i2c_wrdata(i2c_add);
B2 2D0A MOV R16,R10
B3 DFC8 RCALL _i2c_wrdata
(0087) for(i=0;i<i2c_nub;i++)
B4 24AA CLR R10
B5 C005 RJMP 0x00BB
(0088) {
(0089) i2c_wrdata(*i2c_data++);
B6 01F6 MOVW R30,R12
B7 9101 LD R16,Z+
B8 016F MOVW R12,R30
B9 DFC2 RCALL _i2c_wrdata
BA 94A3 INC R10
BB 800C LDD R0,Y+4
BC 14A0 CP R10,R0
BD F3C0 BCS 0x00B6
(0090) }
(0091) i2c_stop();
BE DFD2 RCALL _i2c_stop
BF 940C 010E JMP pop_xgset003C
_i2c_rebyte:
i2c_data --> R10
i2c_add --> R10
C1 92AA ST R10,-Y
C2 2EA0 MOV R10,R16
(0092) }
(0093)
(0094) //i2c读一个字节子程序
(0095) uchar i2c_rebyte(uchar i2c_add)
(0096) {
(0097) uchar i2c_data ;
(0098) do
(0099) {
(0100) i2c_start();
C3 DFB2 RCALL _i2c_start
(0101) i2c_wrdata(0xa0);
C4 EA00 LDI R16,0xA0
C5 DFB6 RCALL _i2c_wrdata
(0102) }
(0103) while((TWSR&0xf8)!=0x18);
C6 B181 IN R24,0x01
C7 7F88 ANDI R24,0xF8
C8 3188 CPI R24,0x18
C9 F7C9 BNE 0x00C3
(0104) //判断总线是否可以操作
(0105) i2c_wrdata(i2c_add);
CA 2D0A MOV R16,R10
CB DFB0 RCALL _i2c_wrdata
(0106) i2c_start();
CC DFA9 RCALL _i2c_start
(0107) i2c_wrdata(0xa1);
CD EA01 LDI R16,0xA1
CE DFAD RCALL _i2c_wrdata
(0108) i2c_data=i2c_redata();
CF DFB3 RCALL _i2c_redata
D0 2EA0 MOV R10,R16
(0109) i2c_stop();
D1 DFBF RCALL _i2c_stop
(0110) return(i2c_data);
D2 2D0A MOV R16,R10
D3 90A9 LD R10,Y+
D4 9508 RET
_i2c_rese:
i --> R10
i2c_nub --> Y,+4
i2c_add --> R10
i2c_data --> R20
D5 940E 011E CALL push_xgset300C
D7 2EA2 MOV R10,R18
D8 01A8 MOVW R20,R16
(0111) }
(0112)
(0113)
(0114) //i2c连续读子程序
(0115) //参数1:16位地址
(0116) //参数2:读取字节数 注:<=64
(0117) //读出的数据只能从全局数组变量获得
(0118) void i2c_rese(uchar *i2c_data,uchar i2c_add,uchar i2c_nub)
(0119) {
(0120) uchar i;
(0121) do
(0122) {
(0123) i2c_start();
D9 DF9C RCALL _i2c_start
(0124) i2c_wrdata(0xa0);
DA EA00 LDI R16,0xA0
DB DFA0 RCALL _i2c_wrdata
(0125) }
(0126) while((TWSR&0xf8)!=0x18);
DC B181 IN R24,0x01
DD 7F88 ANDI R24,0xF8
DE 3188 CPI R24,0x18
DF F7C9 BNE 0x00D9
(0127) //判断总线是否可以操作
(0128) i2c_wrdata(i2c_add);
E0 2D0A MOV R16,R10
E1 DF9A RCALL _i2c_wrdata
(0129) i2c_start();
E2 DF93 RCALL _i2c_start
(0130) i2c_wrdata(0xa1);
E3 EA01 LDI R16,0xA1
E4 DF97 RCALL _i2c_wrdata
(0131) for(i=0;i<(i2c_nub-1);i++) //少循环一次,留给最后发出no ack信号
E5 24AA CLR R10
E6 C006 RJMP 0x00ED
(0132) {
(0133) *i2c_data=i2c_redataack();
E7 DFA2 RCALL _i2c_redataack
E8 01FA MOVW R30,R20
E9 8300 STD Z+0,R16
(0134) i2c_data++;
EA 5F4F SUBI R20,0xFF
EB 4F5F SBCI R21,0xFF
EC 94A3 INC R10
ED 818C LDD R24,Y+4
EE 5081 SUBI R24,1
EF 16A8 CP R10,R24
F0 F3B0 BCS 0x00E7
(0135) }
(0136) *i2c_data=i2c_redata(); //最后一个字节发出no ack信号
F1 DF91 RCALL _i2c_redata
F2 01FA MOVW R30,R20
F3 8300 STD Z+0,R16
(0137) i2c_stop();
F4 DF9C RCALL _i2c_stop
F5 940C 0123 JMP pop_xgset300C
_main:
aa --> Y,+1
F7 9761 SBIW R28,0x11
FILE: D:\16实验程序\I2C读写24C04\页写\write_page.c
(0001) //向24c04连续写入16个字节的程序
(0002) #include<iom16v.h>
(0003) #define uchar unsigned char
(0004) #define uint unsigned int
(0005) #include"i2c.h"
(0006)
(0007)
(0008) //写一个字节
(0009) main()
(0010) {
(0011) //要写入的数据
(0012) uchar aa[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
F8 E88C LDI R24,0x8C
F9 E090 LDI R25,0
FA 01FE MOVW R30,R28
FB 9631 ADIW R30,1
FC E100 LDI R16,0x10
FD E010 LDI R17,0
FE 93FA ST R31,-Y
FF 93EA ST R30,-Y
100 939A ST R25,-Y
101 938A ST R24,-Y
102 940E 0128 CALL asgncblkx
(0013) i2c_init(); //初始化
104 DF6C RCALL _i2c_init
(0014) i2c_wrpage(aa,0x00,16); //字节写入
FILE: <library>
105 E180 LDI R24,0x10
106 8388 STD Y+0,R24
107 2722 CLR R18
108 018E MOVW R16,R28
109 5F0F SUBI R16,0xFF
10A 4F1F SBCI R17,0xFF
10B DF9B RCALL _i2c_wrpage
10C 9661 ADIW R28,0x11
10D 9508 RET
pop_xgset003C:
10E 90A9 LD R10,Y+
10F 90B9 LD R11,Y+
110 90C9 LD R12,Y+
111 90D9 LD R13,Y+
112 9508 RET
push_xgsetF0FC:
113 937A ST R23,-Y
114 936A ST R22,-Y
push_xgset30FC:
115 935A ST R21,-Y
116 934A ST R20,-Y
push_xgset00FC:
117 92FA ST R15,-Y
118 92EA ST R14,-Y
push_xgset003C:
119 92DA ST R13,-Y
11A 92CA ST R12,-Y
11B 92BA ST R11,-Y
11C 92AA ST R10,-Y
11D 9508 RET
push_xgset300C:
11E 935A ST R21,-Y
11F 934A ST R20,-Y
120 92BA ST R11,-Y
121 92AA ST R10,-Y
122 9508 RET
pop_xgset300C:
123 90A9 LD R10,Y+
124 90B9 LD R11,Y+
125 9149 LD R20,Y+
126 9159 LD R21,Y+
127 9508 RET
asgncblkx:
128 93AA ST R26,-Y
129 93BA ST R27,-Y
12A 93EA ST R30,-Y
12B 93FA ST R31,-Y
12C 920A ST R0,-Y
12D 81AF LDD R26,Y+7
12E 85B8 LDD R27,Y+8
12F 81ED LDD R30,Y+5
130 81FE LDD R31,Y+6
131 3000 CPI R16,0
132 0701 CPC R16,R17
133 F031 BEQ 0x013A
134 95D8 ELPM
135 920D ST R0,X+
136 9631 ADIW R30,1
137 5001 SUBI R16,1
138 4010 SBCI R17,0
139 CFF7 RJMP 0x0131
13A 9009 LD R0,Y+
13B 91F9 LD R31,Y+
13C 91E9 LD R30,Y+
13D 91B9 LD R27,Y+
13E 91A9 LD R26,Y+
13F 9624 ADIW R28,4
140 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -