📄 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 + -