?? write-byte.lst
字號:
__start:
__text_start:
46 EFCF LDI R28,0xFF
47 E1D0 LDI R29,0x10
48 BFCD OUT 0x3D,R28
49 BFDE OUT 0x3E,R29
4A 51CE SUBI R28,0x1E
4B 40D0 SBCI R29,0
4C EA0A LDI R16,0xAA
4D 8308 STD Y+0,R16
4E 2400 CLR R0
4F E0E0 LDI R30,0
50 E0F1 LDI R31,1
51 E011 LDI R17,1
52 30E0 CPI R30,0
53 07F1 CPC R31,R17
54 F011 BEQ 0x0057
55 9201 ST R0,Z+
56 CFFB RJMP 0x0052
57 8300 STD Z+0,R16
58 E8EC LDI R30,0x8C
59 E0F0 LDI R31,0
5A E0A0 LDI R26,0
5B E0B1 LDI R27,1
5C E010 LDI R17,0
5D E000 LDI R16,0
5E BF0B OUT 0x3B,R16
5F 38EC CPI R30,0x8C
60 07F1 CPC R31,R17
61 F021 BEQ 0x0066
62 95C8 LPM
63 9631 ADIW R30,1
64 920D ST R0,X+
65 CFF9 RJMP 0x005F
66 940E 00F0 CALL _main
_exit:
68 CFFF RJMP _exit
FILE: D:\16實驗程序\I2C讀寫24C04\寫一個字節\i2c.h
(0001) //i2c通信子程序
(0002)
(0003) //初始化
(0004) void i2c_init()
(0005) {
(0006) DDRC|=(1<<6);
_i2c_init:
69 9AA6 SBI 0x14,6
(0007) PORTC&=~(1<<6); //WP 使能
6A 98AE CBI 0x15,6
(0008) TWBR=0x01 ; //速率=16M/(16+2*16)=33.3k
6B E081 LDI R24,1
6C B980 OUT 0x00,R24
(0009) TWSR=0x01 ; //分頻因子=4
6D B981 OUT 0x01,R24
6E 9508 RET
(0010) }
(0011)
(0012) //開始信號
(0013) void i2c_start()
(0014) {
(0015) TWCR=0xa4 ;
_i2c_start:
6F EA84 LDI R24,0xA4
70 BF86 OUT 0x36,R24
(0016) while(!(TWCR&0x80));
71 B626 IN R2,0x36
72 FE27 SBRS R2,7
73 CFFD RJMP 0x0071
74 9508 RET
(0017) }
(0018)
(0019) //寫數據
(0020) void i2c_wrdata(uchar i2c_data)
(0021) {
(0022) TWDR=(i2c_data);
_i2c_wrdata:
i2c_data --> R16
75 B903 OUT 0x03,R16
(0023) TWCR=0x84 ;
76 E884 LDI R24,0x84
77 BF86 OUT 0x36,R24
(0024) while(!(TWCR&0x80));
78 B626 IN R2,0x36
79 FE27 SBRS R2,7
7A CFFD RJMP 0x0078
7B 9508 RET
(0025) }
(0026)
(0027) //讀數據noack
(0028) uchar i2c_redata()
(0029) {
(0030) uchar i2c_data ;
(0031) TWCR=0x84 ;
_i2c_redata:
i2c_data --> R16
7C E884 LDI R24,0x84
7D BF86 OUT 0x36,R24
(0032) while(!(TWCR&0x80));
7E B626 IN R2,0x36
7F FE27 SBRS R2,7
80 CFFD RJMP 0x007E
(0033) i2c_data=TWDR ;
81 B103 IN R16,0x03
(0034) return(i2c_data);
82 9508 RET
(0035) }
(0036)
(0037) //讀數據ack
(0038) uchar i2c_redataack()
(0039) {
(0040) uchar i2c_data ;
(0041) TWCR=0xc4 ;
_i2c_redataack:
i2c_data --> R16
83 EC84 LDI R24,0xC4
84 BF86 OUT 0x36,R24
(0042) while(!(TWCR&0x80));
85 B626 IN R2,0x36
86 FE27 SBRS R2,7
87 CFFD RJMP 0x0085
(0043) i2c_data=TWDR ;
88 B103 IN R16,0x03
(0044) return(i2c_data);
89 9508 RET
(0045) }
(0046)
(0047) //停止信號
(0048) void i2c_stop()
(0049) {
(0050) TWCR=0x94 ;
_i2c_stop:
8A E984 LDI R24,0x94
8B BF86 OUT 0x36,R24
8C 9508 RET
_i2c_wrbyte:
i2c_add --> R12
i2c_data --> R10
8D 92AA ST R10,-Y
8E 92CA ST R12,-Y
8F 2EC2 MOV R12,R18
90 2EA0 MOV R10,R16
(0051) }
(0052)
(0053) //i2c的寫字節子程序
(0054) void i2c_wrbyte(uchar i2c_data,uchar i2c_add)
(0055) {
(0056) do
(0057) {
(0058) i2c_start();
91 DFDD RCALL _i2c_start
(0059) i2c_wrdata(0xa0);
92 EA00 LDI R16,0xA0
93 DFE1 RCALL _i2c_wrdata
(0060) }
(0061) while((TWSR&0xf8)!=0x18); //判斷總線是否可以操作
94 B181 IN R24,0x01
95 7F88 ANDI R24,0xF8
96 3188 CPI R24,0x18
97 F7C9 BNE 0x0091
(0062) i2c_wrdata(i2c_add);
98 2D0C MOV R16,R12
99 DFDB RCALL _i2c_wrdata
(0063) i2c_wrdata(i2c_data);
9A 2D0A MOV R16,R10
9B DFD9 RCALL _i2c_wrdata
(0064) i2c_stop();
9C DFED RCALL _i2c_stop
9D 90C9 LD R12,Y+
9E 90A9 LD R10,Y+
9F 9508 RET
_i2c_wrpage:
i --> R10
i2c_nub --> Y,+4
i2c_add --> R10
i2c_data --> R12
A0 940E 0100 CALL push_xgset003C
A2 2EA2 MOV R10,R18
A3 0168 MOVW R12,R16
(0065) }
(0066)
(0067) //i2c的頁寫子程序
(0068) //參數1:要寫入的數組指針
(0069) //參數2:寫入的首地址
(0070) //參數3:數組的單元數
(0071) void i2c_wrpage(uchar *i2c_data,uchar i2c_add,uchar i2c_nub)
(0072) {
(0073) uchar i;
(0074) do
(0075) {
(0076) i2c_start();
A4 DFCA RCALL _i2c_start
(0077) i2c_wrdata(0xa0);
A5 EA00 LDI R16,0xA0
A6 DFCE RCALL _i2c_wrdata
(0078) }
(0079) while((TWSR&0xf8)!=0x18);
A7 B181 IN R24,0x01
A8 7F88 ANDI R24,0xF8
A9 3188 CPI R24,0x18
AA F7C9 BNE 0x00A4
(0080) //判斷總線是否可以操作
(0081) i2c_wrdata(i2c_add);
AB 2D0A MOV R16,R10
AC DFC8 RCALL _i2c_wrdata
(0082) for(i=0;i<i2c_nub;i++)
AD 24AA CLR R10
AE C005 RJMP 0x00B4
(0083) {
(0084) i2c_wrdata(*i2c_data++);
AF 01F6 MOVW R30,R12
B0 9101 LD R16,Z+
B1 016F MOVW R12,R30
B2 DFC2 RCALL _i2c_wrdata
B3 94A3 INC R10
B4 800C LDD R0,Y+4
B5 14A0 CP R10,R0
B6 F3C0 BCS 0x00AF
(0085) }
(0086) i2c_stop();
B7 DFD2 RCALL _i2c_stop
B8 940C 00F5 JMP pop_xgset003C
_i2c_rebyte:
i2c_data --> R10
i2c_add --> R10
BA 92AA ST R10,-Y
BB 2EA0 MOV R10,R16
(0087) }
(0088)
(0089) //i2c讀一個字節子程序
(0090) uchar i2c_rebyte(uchar i2c_add)
(0091) {
(0092) uchar i2c_data ;
(0093) do
(0094) {
(0095) i2c_start();
BC DFB2 RCALL _i2c_start
(0096) i2c_wrdata(0xa0);
BD EA00 LDI R16,0xA0
BE DFB6 RCALL _i2c_wrdata
(0097) }
(0098) while((TWSR&0xf8)!=0x18);
BF B181 IN R24,0x01
C0 7F88 ANDI R24,0xF8
C1 3188 CPI R24,0x18
C2 F7C9 BNE 0x00BC
(0099) //判斷總線是否可以操作
(0100) i2c_wrdata(i2c_add);
C3 2D0A MOV R16,R10
C4 DFB0 RCALL _i2c_wrdata
(0101) i2c_start();
C5 DFA9 RCALL _i2c_start
(0102) i2c_wrdata(0xa1);
C6 EA01 LDI R16,0xA1
C7 DFAD RCALL _i2c_wrdata
(0103) i2c_data=i2c_redata();
C8 DFB3 RCALL _i2c_redata
C9 2EA0 MOV R10,R16
(0104) i2c_stop();
CA DFBF RCALL _i2c_stop
(0105) return(i2c_data);
CB 2D0A MOV R16,R10
CC 90A9 LD R10,Y+
CD 9508 RET
_i2c_rese:
i --> R10
i2c_nub --> Y,+4
i2c_add --> R10
i2c_data --> R20
CE 940E 0105 CALL push_xgset300C
D0 2EA2 MOV R10,R18
D1 01A8 MOVW R20,R16
(0106) }
(0107)
(0108) //i2c連續讀子程序
(0109) //參數1:16位地址
(0110) //參數2:讀取字節數 注:<=64
(0111) //讀出的數據只能從全局數組變量獲得
(0112) void i2c_rese(uchar *i2c_data,uchar i2c_add,uchar i2c_nub)
(0113) {
(0114) uchar i;
(0115) do
(0116) {
(0117) i2c_start();
D2 DF9C RCALL _i2c_start
(0118) i2c_wrdata(0xa0);
D3 EA00 LDI R16,0xA0
D4 DFA0 RCALL _i2c_wrdata
(0119) }
(0120) while((TWSR&0xf8)!=0x18);
D5 B181 IN R24,0x01
D6 7F88 ANDI R24,0xF8
D7 3188 CPI R24,0x18
D8 F7C9 BNE 0x00D2
(0121) //判斷總線是否可以操作
(0122) i2c_wrdata(i2c_add);
D9 2D0A MOV R16,R10
DA DF9A RCALL _i2c_wrdata
(0123) i2c_start();
DB DF93 RCALL _i2c_start
(0124) i2c_wrdata(0xa1);
DC EA01 LDI R16,0xA1
DD DF97 RCALL _i2c_wrdata
(0125) for(i=0;i<(i2c_nub-1);i++) //少循環一次,留給最后發出no ack信號
DE 24AA CLR R10
DF C006 RJMP 0x00E6
(0126) {
(0127) *i2c_data=i2c_redataack();
E0 DFA2 RCALL _i2c_redataack
E1 01FA MOVW R30,R20
E2 8300 STD Z+0,R16
(0128) i2c_data++;
E3 5F4F SUBI R20,0xFF
E4 4F5F SBCI R21,0xFF
E5 94A3 INC R10
E6 818C LDD R24,Y+4
E7 5081 SUBI R24,1
E8 16A8 CP R10,R24
E9 F3B0 BCS 0x00E0
(0129) }
(0130) *i2c_data=i2c_redata(); //最后一個字節發出no ack信號
EA DF91 RCALL _i2c_redata
EB 01FA MOVW R30,R20
EC 8300 STD Z+0,R16
(0131) i2c_stop();
ED DF9C RCALL _i2c_stop
EE 940C 010A JMP pop_xgset300C
FILE: D:\16實驗程序\I2C讀寫24C04\寫一個字節\write-byte.c
(0001) //向24c04寫一個字節數據程序
(0002) #include<iom16v.h>
(0003) #define uchar unsigned char
(0004) #define uint unsigned int
(0005) #include"i2c.h"
(0006)
(0007)
(0008) //寫一個字節
(0009) void main()
(0010) {
(0011) i2c_init(); //初始化
_main:
F0 DF78 RCALL _i2c_init
(0012) i2c_wrbyte(0x07,0x12); //字節寫進地址0x12
FILE: <library>
F1 E122 LDI R18,0x12
F2 E007 LDI R16,7
F3 DF99 RCALL _i2c_wrbyte
F4 9508 RET
pop_xgset003C:
F5 90A9 LD R10,Y+
F6 90B9 LD R11,Y+
F7 90C9 LD R12,Y+
F8 90D9 LD R13,Y+
F9 9508 RET
push_xgsetF0FC:
FA 937A ST R23,-Y
FB 936A ST R22,-Y
push_xgset30FC:
FC 935A ST R21,-Y
FD 934A ST R20,-Y
push_xgset00FC:
FE 92FA ST R15,-Y
FF 92EA ST R14,-Y
push_xgset003C:
100 92DA ST R13,-Y
101 92CA ST R12,-Y
102 92BA ST R11,-Y
103 92AA ST R10,-Y
104 9508 RET
push_xgset300C:
105 935A ST R21,-Y
106 934A ST R20,-Y
107 92BA ST R11,-Y
108 92AA ST R10,-Y
109 9508 RET
pop_xgset300C:
10A 90A9 LD R10,Y+
10B 90B9 LD R11,Y+
10C 9149 LD R20,Y+
10D 9159 LD R21,Y+
10E 9508 RET
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -