?? i2c.lst
字號:
C51 COMPILER V8.09 I2C 11/28/2004 05:44:22 PAGE 1
C51 COMPILER V8.09, COMPILATION OF MODULE I2C
OBJECT MODULE PLACED IN I2C.OBJ
COMPILER INVOKED BY: D:\Keil\C51\BIN\C51.EXE I2C.c BROWSE DEBUG OBJECTEXTEND
line level source
1 /*
2 I2C.c
3 標準80C51單片機模擬I2C總線的主機程序
4 Copyright (c) 2005,廣州周立功單片機發展有限公司
5 All rights reserved.
6 本程序僅供學習參考,不提供任何可靠性方面的擔保;請勿用于商業目的
7 */
8
9 #include "I2C.h"
10
11 //定義延時變量,用于宏I2C_Delay()
12 unsigned char data I2C_Delay_t;
13
14 /*
15 宏定義:I2C_Delay()
16 功能:延時,模擬I2C總線專用
17 */
18 #define I2C_Delay()\
19 {\
20 I2C_Delay_t = (I2C_DELAY_VALUE);\
21 while ( --I2C_Delay_t != 0 );\
22 }
23
24 /*
25 函數:I2C_Init()
26 功能:I2C總線初始化,使總線處于空閑狀態
27 說明:在main()函數的開始處,通常應當要執行一次本函數
28 */
29 void I2C_Init()
30 {
31 1 I2C_SCL = 1;
32 1 I2C_Delay();
33 1 I2C_SDA = 1;
34 1 I2C_Delay();
35 1 }
36
37 /*
38 函數:I2C_Start()
39 功能:產生I2C總線的起始狀態
40 說明:
41 SCL處于高電平期間,當SDA出現下降沿時啟動I2C總線
42 不論SDA和SCL處于什么電平狀態,本函數總能正確產生起始狀態
43 本函數也可以用來產生重復起始狀態
44 本函數執行后,I2C總線處于忙狀態
45 */
46 void I2C_Start()
47 {
48 1 I2C_SDA = 1;
49 1 I2C_Delay();
50 1 I2C_SCL = 1;
51 1 I2C_Delay();
52 1 I2C_SDA = 0;
53 1 I2C_Delay();
54 1 I2C_SCL = 0;
55 1 I2C_Delay();
C51 COMPILER V8.09 I2C 11/28/2004 05:44:22 PAGE 2
56 1 }
57
58 /*
59 函數:I2C_Write()
60 功能:向I2C總線寫1個字節的數據
61 參數:
62 dat:要寫到總線上的數據
63 */
64 void I2C_Write(char dat)
65 {
66 1 unsigned char t = 8;
67 1 do
68 1 {
69 2 I2C_SDA = (bit)(dat & 0x80);
70 2 dat <<= 1;
71 2 I2C_SCL = 1;
72 2 I2C_Delay();
73 2 I2C_SCL = 0;
74 2 I2C_Delay();
75 2 } while ( --t != 0 );
76 1 }
77
78 /*
79 函數:I2C_Read()
80 功能:從從機讀取1個字節的數據
81 返回:讀取的一個字節數據
82 */
83 char I2C_Read()
84 {
85 1 char dat;
86 1 unsigned char t = 8;
87 1 I2C_SDA = 1; //在讀取數據之前,要把SDA拉高
88 1 do
89 1 {
90 2 I2C_SCL = 1;
91 2 I2C_Delay();
92 2 dat <<= 1;
93 2 if ( I2C_SDA ) dat |= 0x01;
94 2 I2C_SCL = 0;
95 2 I2C_Delay();
96 2 } while ( --t != 0 );
97 1 return dat;
98 1 }
99
100 /*
101 函數:I2C_GetAck()
102 功能:讀取從機應答位
103 返回:
104 0:從機應答
105 1:從機非應答
106 說明:
107 從機在收到每個字節的數據后,要產生應答位
108 從機在收到最后1個字節的數據后,一般要產生非應答位
109 */
110 bit I2C_GetAck()
111 {
112 1 bit ack;
113 1 I2C_SDA = 1;
114 1 I2C_Delay();
115 1 I2C_SCL = 1;
116 1 I2C_Delay();
117 1 ack = I2C_SDA;
C51 COMPILER V8.09 I2C 11/28/2004 05:44:22 PAGE 3
118 1 I2C_SCL = 0;
119 1 I2C_Delay();
120 1 return ack;
121 1 }
122
123 /*
124 函數:I2C_PutAck()
125 功能:主機產生應答位或非應答位
126 參數:
127 ack=0:主機產生應答位
128 ack=1:主機產生非應答位
129 說明:
130 主機在接收完每一個字節的數據后,都應當產生應答位
131 主機在接收完最后一個字節的數據后,應當產生非應答位
132 */
133 void I2C_PutAck(bit ack)
134 {
135 1 I2C_SDA = ack;
136 1 I2C_Delay();
137 1 I2C_SCL = 1;
138 1 I2C_Delay();
139 1 I2C_SCL = 0;
140 1 I2C_Delay();
141 1 }
142
143 /*
144 函數:I2C_Stop()
145 功能:產生I2C總線的停止狀態
146 說明:
147 SCL處于高電平期間,當SDA出現上升沿時停止I2C總線
148 不論SDA和SCL處于什么電平狀態,本函數總能正確產生停止狀態
149 本函數執行后,I2C總線處于空閑狀態
150 */
151 void I2C_Stop()
152 {
153 1 unsigned int t = I2C_STOP_WAIT_VALUE;
154 1 I2C_SDA = 0;
155 1 I2C_Delay();
156 1 I2C_SCL = 1;
157 1 I2C_Delay();
158 1 I2C_SDA = 1;
159 1 I2C_Delay();
160 1 while ( --t != 0 ); //在下一次產生Start之前,要加一定的延時
161 1 }
162
163 /*
164 函數:I2C_Puts()
165 功能:I2C總線綜合發送函數,向從機發送多個字節的數據
166 參數:
167 SlaveAddr:從機地址(7位純地址,不含讀寫位)
168 SubAddr:從機的子地址
169 SubMod:子地址模式,0-無子地址,1-單字節子地址,2-雙字節子地址
170 *dat:要發送的數據
171 Size:數據的字節數
172 返回:
173 0:發送成功
174 1:在發送過程中出現異常
175 說明:
176 本函數能夠很好地適應所有常見的I2C器件,不論其是否有子地址
177 當從機沒有子地址時,參數SubAddr任意,而SubMod應當為0
178 */
179 bit I2C_Puts
C51 COMPILER V8.09 I2C 11/28/2004 05:44:22 PAGE 4
180 (
181 unsigned char SlaveAddr,
182 unsigned int SubAddr,
183 unsigned char SubMod,
184 char *dat,
185 unsigned int Size
186 )
187 {
188 1 //定義臨時變量
189 1 unsigned char i;
190 1 char a[3];
191 1 //檢查長度
192 1 if ( Size == 0 ) return 0;
193 1 //準備從機地址
194 1 a[0] = (SlaveAddr << 1);
195 1 //檢查子地址模式
196 1 if ( SubMod > 2 ) SubMod = 2;
197 1 //確定子地址
198 1 switch ( SubMod )
199 1 {
200 2 case 0:
201 2 break;
202 2 case 1:
203 2 a[1] = (char)(SubAddr);
204 2 break;
205 2 case 2:
206 2 a[1] = (char)(SubAddr >> 8);
207 2 a[2] = (char)(SubAddr);
208 2 break;
209 2 default:
210 2 break;
211 2 }
212 1 //發送從機地址,接著發送子地址(如果有子地址的話)
213 1 SubMod++;
214 1 I2C_Start();
215 1 for ( i=0; i<SubMod; i++ )
216 1 {
217 2 I2C_Write(a[i]);
218 2 if ( I2C_GetAck() )
219 2 {
220 3 I2C_Stop();
221 3 return 1;
222 3 }
223 2 }
224 1 //發送數據
225 1 do
226 1 {
227 2 I2C_Write(*dat++);
228 2 if ( I2C_GetAck() ) break;
229 2 } while ( --Size != 0 );
230 1 //發送完畢,停止I2C總線,并返回結果
231 1 I2C_Stop();
232 1 if ( Size == 0 )
233 1 {
234 2 return 0;
235 2 }
236 1 else
237 1 {
238 2 return 1;
239 2 }
240 1 }
241
C51 COMPILER V8.09 I2C 11/28/2004 05:44:22 PAGE 5
242 /*
243 函數:I2C_Gets()
244 功能:I2C總線綜合接收函數,從從機接收多個字節的數據
245 參數:
246 SlaveAddr:從機地址(7位純地址,不含讀寫位)
247 SubAddr:從機的子地址
248 SubMod:子地址模式,0-無子地址,1-單字節子地址,2-雙字節子地址
249 *dat:保存接收到的數據
250 Size:數據的字節數
251 返回:
252 0:接收成功
253 1:在接收過程中出現異常
254 說明:
255 本函數能夠很好地適應所有常見的I2C器件,不論其是否有子地址
256 當從機沒有子地址時,參數SubAddr任意,而SubMod應當為0
257 */
258 bit I2C_Gets
259 (
260 unsigned char SlaveAddr,
261 unsigned int SubAddr,
262 unsigned char SubMod,
263 char *dat,
264 unsigned int Size
265 )
266 {
267 1 //定義臨時變量
268 1 unsigned char i;
269 1 char a[3];
270 1 //檢查長度
271 1 if ( Size == 0 ) return 0;
272 1 //準備從機地址
273 1 a[0] = (SlaveAddr << 1);
274 1 //檢查子地址模式
275 1 if ( SubMod > 2 ) SubMod = 2;
276 1 //如果是有子地址的從機,則要先發送從機地址和子地址
277 1 if ( SubMod != 0 )
278 1 {
279 2 //確定子地址
280 2 if ( SubMod == 1 )
281 2 {
282 3 a[1] = (char)(SubAddr);
283 3 }
284 2 else
285 2 {
286 3 a[1] = (char)(SubAddr >> 8);
287 3 a[2] = (char)(SubAddr);
288 3 }
289 2 //發送從機地址,接著發送子地址
290 2 SubMod++;
291 2 I2C_Start();
292 2 for ( i=0; i<SubMod; i++ )
293 2 {
294 3 I2C_Write(a[i]);
295 3 if ( I2C_GetAck() )
296 3 {
297 4 I2C_Stop();
298 4 return 1;
299 4 }
300 3 }
301 2 }
302 1 //這里的I2C_Start()對于有子地址的從機是重復起始狀態
303 1 //對于無子地址的從機則是正常的起始狀態
C51 COMPILER V8.09 I2C 11/28/2004 05:44:22 PAGE 6
304 1 I2C_Start();
305 1 //發送從機地址
306 1 I2C_Write(a[0]+1);
307 1 if ( I2C_GetAck() )
308 1 {
309 2 I2C_Stop();
310 2 return 1;
311 2 }
312 1 //接收數據
313 1 for (;;)
314 1 {
315 2 *dat++ = I2C_Read();
316 2 if ( --Size == 0 )
317 2 {
318 3 I2C_PutAck(1);
319 3 break;
320 3 }
321 2 I2C_PutAck(0);
322 2 }
323 1 //接收完畢,停止I2C總線,并返回結果
324 1 I2C_Stop();
325 1 return 0;
326 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 449 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 1 24
IDATA SIZE = ---- ----
BIT SIZE = ---- 2
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -