📄 i2c.lst
字号:
C51 COMPILER V7.04 I2C 12/26/2007 09:33:09 PAGE 1
C51 COMPILER V7.04, COMPILATION OF MODULE I2C
OBJECT MODULE PLACED IN I2C.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE I2C.c BROWSE DEBUG OBJECTEXTEND CODE
stmt level source
1 /***********************************************************************/
2 /* 文件名 :I2C.c
3 /* 芯片 :Atmel AT89C51
4 /* 作者 :Ericson
5 /* 日期 :2007.11.15
6 /* 功能描述:本文件为I2C串行通信协议提供支持,通过AT89C51的P00和P01口模拟
7 实现I2C协议规范,并通过I2C通信协议实现对EEPROM AT24C32的写入
8 和读出操作。
9
10 /***********************************************************************/
11
12 //***********************************************************************
13 //包含头文件
14 #include "I2C.h"
15
16 //***********************************************************************
17 //端口定义
18 sbit SCL = P0^0; //I2C编程端口--SCL
19 sbit SDA = P0^1; //I2C编程端口--SDA
20
21 //***********************************************************************
22 //I2C串行通信启动函数
23 void I2C_Start(void)
24 {
25 1 SDA = 1;
26 1 _nop_();
27 1 SCL = 1;
28 1 SomeNOP();
29 1 SDA = 0; //数据线保持高电平5个指令周期后变为低电平,I2C通信开始
30 1 SomeNOP(); //SDA:5(高)+4(低)
31 1 SCL = 0; //SCL: 9(高)
32 1 _nop_();
33 1 _nop_();
34 1 }
35
36 //***********************************************************************
37 //I2C串行通信结束函数
38 void I2C_Stop(void)
39 {
40 1 SDA = 0;
41 1 _nop_();
42 1 _nop_();
43 1 SCL = 1;
44 1 SomeNOP();
45 1 SDA = 1;
46 1 SomeNOP();
47 1 }
48
49 //***********************************************************************
50 //I2C串行通信发送应答位函数
51 void I2C_ACK(void)
52 {
53 1 SDA = 0;
54 1 _nop_();
55 1 _nop_();
C51 COMPILER V7.04 I2C 12/26/2007 09:33:09 PAGE 2
56 1 SCL = 1;
57 1 SomeNOP();
58 1 SCL = 0;
59 1 _nop_();
60 1 _nop_();
61 1 }
62
63
64 //**********************************************************************
65 //I2C串行通信发送非应答位函数
66 void I2C_NoACK(void)
67 {
68 1 SDA = 1;
69 1 _nop_();
70 1 _nop_();
71 1 SCL = 1;
72 1 SomeNOP();
73 1 SCL = 0;
74 1 _nop_();
75 1 _nop_();
76 1 }
77
78 //***********************************************************************
79 //I2C串行通信写入一个字节函数
80 void I2C_WriteByte(uchar ch)
81 {
82 1 uchar index = 8;
83 1 while(index--)
84 1 {
85 2 SCL = 0;
86 2 _nop_();
87 2 _nop_();
88 2 SDA = (bit)(ch&0x80);
89 2 SomeNOP();
90 2 SCL = 1;
91 2 SomeNOP();
92 2 ch <<= 1;
93 2 }
94 1 SCL = 0;
95 1 _nop_();
96 1 _nop_();
97 1 SDA = 1;
98 1 _nop_();
99 1 _nop_();
100 1 SCL = 1;
101 1 _nop_();
102 1 _nop_();
103 1 _nop_();
104 1 if(SDA == 1) ACK = 0;
105 1 else ACK = 1;
106 1 SCL = 0;
107 1 _nop_();
108 1 _nop_();
109 1 }
110
111 //***********************************************************************
112 //I2C串行通信读出一个字节函数
113 uchar I2C_ReadByte(void)
114 {
115 1 uchar index = 8;
116 1 uchar Data = 0;
117 1 SDA = 1;
C51 COMPILER V7.04 I2C 12/26/2007 09:33:09 PAGE 3
118 1 while(index--)
119 1 {
120 2 Data <<= 1;
121 2 _nop_();
122 2 SCL = 0;
123 2 SomeNOP();
124 2 SCL = 1;
125 2 _nop_();
126 2 _nop_();
127 2 if(SDA == 1) Data += 1;
128 2 }
129 1 SCL = 0;
130 1 _nop_();
131 1 _nop_();
132 1 return Data;
133 1 }
134
135
136 //***********************************************************************
137 //通过I2C接口向EEPROM写入一个字节数据函数
138 //参数说明:sla -- 待写入数据的EEPROM的控制字节,1 0 1 0 A2 A1 A0 R/W(R/W不起作用,为0)
139 // addr -- 待写入数据的EEPROM的16位存储单元地址(针对AT24C32或AT24C64设计)
140 // ch -- 待写入EEPROM的数据
141 bit NVM_WriteB(uchar sla,uint addr,uchar ch)
142 {
143 1 uchar haddr,laddr;
144 1 laddr = (uchar)(addr&0xFF); //存储单元低字节地址
145 1 haddr = (uchar)((addr>>8)&0xFF); //存储单元高字节地址
146 1 I2C_Start();
147 1 I2C_WriteByte(sla);
148 1 if(ACK == 0) return(0);
149 1 I2C_WriteByte(haddr);
150 1 if(ACK == 0) return(0);
151 1 I2C_WriteByte(laddr);
152 1 if(ACK == 0) return(0);
153 1 I2C_WriteByte(ch);
154 1 if(ACK == 0) return(0);
155 1 I2C_Stop();
156 1 return(1);
157 1 }
158
159
160 //***********************************************************************
161 //通过I2C接口从EEPROM读出一个字节数据函数,结果放在ch指向的地址单元中
162 //参数说明:sla -- 待读出数据的EEPROM的控制字节,1 0 1 0 A2 A1 A0 R/W(R/W不起作用,为0)
163 // addr -- 待读出数据的EEPROM的16位存储单元地址(针对AT24C32或AT24C64设计)
164 // ch -- 用于保存从EEPROM读出的数据
165 bit NVM_ReadB(uchar sla,uint addr,uchar *ch)
166 {
167 1 uchar haddr,laddr;
168 1 laddr = (uchar)(addr&0xFF); //存储单元低字节地址
169 1 haddr = (uchar)((addr>>8)&0xFF); //存储单元高字节地址
170 1 I2C_Start();
171 1 I2C_WriteByte(sla);
172 1 if(ACK == 0) return(0);
173 1 I2C_WriteByte(haddr);
174 1 if(ACK == 0) return(0);
175 1 I2C_WriteByte(laddr);
176 1 if(ACK == 0) return(0);
177 1 I2C_Start();
178 1 I2C_WriteByte(sla+1);
179 1 if(ACK == 0) return(0);
C51 COMPILER V7.04 I2C 12/26/2007 09:33:09 PAGE 4
180 1 *ch = I2C_ReadByte();
181 1 I2C_NoACK();
182 1 I2C_Stop();
183 1 return(1);
184 1 }
185
186 //***********************************************************************
187 //通过I2C接口向EEPROM写入一个字符串函数
188 //参数说明:sla -- 待写入数据的EEPROM的控制字节,1 0 1 0 A2 A1 A0 R/W(R/W不起作用,为0)
189 // addr -- 待写入数据的EEPROM的16位存储单元地址(针对AT24C32或AT24C64设计)
190 // str -- 待写入EEPROM的数据数组的首地址
191 // length-- 待写入EEPROM的数据数组长度
192 bit NVM_WriteStr(uchar sla,uint addr,uchar *str,uchar length)
193 {
194 1 uchar index,temp;
195 1 uchar haddr,laddr;
196 1 laddr = (uchar)(addr&0xFF); //存储单元低字节地址
197 1 haddr = (uchar)((addr>>8)&0xFF); //存储单元高字节地址
198 1 I2C_Start();
199 1 I2C_WriteByte(sla);
200 1 if(ACK == 0) return(0);
201 1 I2C_WriteByte(haddr);
202 1 if(ACK == 0) return(0);
203 1 I2C_WriteByte(laddr);
204 1 if(ACK == 0) return(0);
205 1 for(index=0;index<length;index++)
206 1 {
207 2 temp = *(str+index);
208 2 I2C_WriteByte(temp);
209 2 if(ACK == 0) return(0);
210 2 }
211 1 I2C_Stop();
212 1 return(1);
213 1 }
214
215 //***********************************************************************
216 //通过I2C接口从EEPROM读出一个字符串函数,结果放在ch指向的地址单元中
217 //参数说明:sla -- 待读出数据的EEPROM的控制字节,1 0 1 0 A2 A1 A0 R/W(R/W不起作用,为0)
218 // addr -- 待读出数据的EEPROM的16位存储单元地址(针对AT24C32或AT24C64设计)
219 // str -- 待写入EEPROM的数据数组的首地址
220 // length-- 待写入EEPROM的数据数组长度
221 bit NVM_ReadStr(uchar sla,uint addr,uchar *str,uchar length)
222 {
223 1 uchar index;
224 1 uchar haddr,laddr;
225 1 laddr = (uchar)(addr&0xFF); //存储单元低字节地址
226 1 haddr = (uchar)((addr>>8)&0xFF); //存储单元高字节地址
227 1 I2C_Start();
228 1 I2C_WriteByte(sla);
229 1 if(ACK == 0) return(0);
230 1 I2C_WriteByte(haddr);
231 1 if(ACK == 0) return(0);
232 1 I2C_WriteByte(laddr);
233 1 if(ACK == 0) return(0);
234 1 I2C_Start();
235 1 I2C_WriteByte(sla+1);
236 1 if(ACK == 0) return(0);
237 1 for(index=0;index<length;index++)
238 1 {
239 2 *(str+index) = I2C_ReadByte();
240 2 I2C_ACK();
241 2 }
C51 COMPILER V7.04 I2C 12/26/2007 09:33:09 PAGE 5
242 1 I2C_NoACK();
243 1 I2C_Stop();
244 1 return(1);
245 1 }
246
247 //结束
248
249
250
251
252
253
254
C51 COMPILER V7.04 I2C 12/26/2007 09:33:09 PAGE 6
ASSEMBLY LISTING OF GENERATED OBJECT CODE
; FUNCTION I2C_Start (BEGIN)
; SOURCE LINE # 23
; SOURCE LINE # 24
; SOURCE LINE # 25
0000 D281 SETB SDA
; SOURCE LINE # 26
0002 00 NOP
; SOURCE LINE # 27
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -