📄 i2c.lst
字号:
C51 COMPILER V7.09 I2C 12/05/2007 16:14:14 PAGE 1
C51 COMPILER V7.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) 2006,广州周立功单片机发展有限公司
5 All rights reserved.
6 本程序仅供学习参考,不提供任何可靠性方面的担保;请勿用于商业目的
7 */
8
9
10 #include "I2C.h"
11
12
13 //定义延时变量,用于宏I2C_Delay()
14 unsigned char data I2C_Delay_t;
15
16 /*
17 宏定义:I2C_Delay()
18 功能:延时,模拟I2C总线专用
19 */
20 #define I2C_Delay()\
21 {\
22 I2C_Delay_t = (I2C_DELAY_VALUE);\
23 while ( --I2C_Delay_t != 0 );\
24 }
25
26
27 /*
28 函数:I2C_Init()
29 功能:I2C总线初始化,使总线处于空闲状态
30 说明:在main()函数的开始处,通常应当要执行一次本函数
31 */
32 void I2C_Init()
33 {
34 1 I2C_SCL = 1;
35 1 I2C_Delay();
36 1 I2C_SDA = 1;
37 1 I2C_Delay();
38 1 }
39
40
41 /*
42 函数:I2C_Start()
43 功能:产生I2C总线的起始状态
44 说明:
45 SCL处于高电平期间,当SDA出现下降沿时启动I2C总线
46 不论SDA和SCL处于什么电平状态,本函数总能正确产生起始状态
47 本函数也可以用来产生重复起始状态
48 本函数执行后,I2C总线处于忙状态
49 */
50 void I2C_Start()
51 {
52 1 I2C_SDA = 1;
53 1 I2C_Delay();
54 1 I2C_SCL = 1;
55 1 I2C_Delay();
C51 COMPILER V7.09 I2C 12/05/2007 16:14:14 PAGE 2
56 1 I2C_SDA = 0;
57 1 I2C_Delay();
58 1 I2C_SCL = 0;
59 1 I2C_Delay();
60 1 }
61
62
63 /*
64 函数:I2C_Write()
65 功能:向I2C总线写1个字节的数据
66 参数:
67 dat:要写到总线上的数据
68 */
69 void I2C_Write(unsigned char dat)
70 {
71 1 unsigned char t = 8;
72 1 do
73 1 {
74 2 I2C_SDA = (bit)(dat & 0x80);
75 2 dat <<= 1;
76 2 I2C_SCL = 1;
77 2 I2C_Delay();
78 2 I2C_SCL = 0;
79 2 I2C_Delay();
80 2 } while ( --t != 0 );
81 1 }
82
83
84 /*
85 函数:I2C_Read()
86 功能:从从机读取1个字节的数据
87 返回:读取的一个字节数据
88 */
89 unsigned char I2C_Read()
90 {
91 1 unsigned char dat;
92 1 unsigned char t = 8;
93 1 I2C_SDA = 1; //在读取数据之前,要把SDA拉高
94 1 do
95 1 {
96 2 I2C_SCL = 1;
97 2 I2C_Delay();
98 2 dat <<= 1;
99 2 if ( I2C_SDA ) dat |= 0x01;
100 2 I2C_SCL = 0;
101 2 I2C_Delay();
102 2 } while ( --t != 0 );
103 1 return dat;
104 1 }
105
106
107 /*
108 函数:I2C_GetAck()
109 功能:读取从机应答位
110 返回:
111 0:从机应答
112 1:从机非应答
113 说明:
114 从机在收到每个字节的数据后,要产生应答位
115 从机在收到最后1个字节的数据后,一般要产生非应答位
116 */
117 bit I2C_GetAck()
C51 COMPILER V7.09 I2C 12/05/2007 16:14:14 PAGE 3
118 {
119 1 bit ack;
120 1 I2C_SDA = 1;
121 1 I2C_Delay();
122 1 I2C_SCL = 1;
123 1 I2C_Delay();
124 1 ack = I2C_SDA;
125 1 I2C_SCL = 0;
126 1 I2C_Delay();
127 1 return ack;
128 1 }
129
130
131 /*
132 函数:I2C_PutAck()
133 功能:主机产生应答位或非应答位
134 参数:
135 ack=0:主机产生应答位
136 ack=1:主机产生非应答位
137 说明:
138 主机在接收完每一个字节的数据后,都应当产生应答位
139 主机在接收完最后一个字节的数据后,应当产生非应答位
140 */
141 void I2C_PutAck(bit ack)
142 {
143 1 I2C_SDA = ack;
144 1 I2C_Delay();
145 1 I2C_SCL = 1;
146 1 I2C_Delay();
147 1 I2C_SCL = 0;
148 1 I2C_Delay();
149 1 }
150
151
152 /*
153 函数:I2C_Stop()
154 功能:产生I2C总线的停止状态
155 说明:
156 SCL处于高电平期间,当SDA出现上升沿时停止I2C总线
157 不论SDA和SCL处于什么电平状态,本函数总能正确产生停止状态
158 本函数执行后,I2C总线处于空闲状态
159 */
160 void I2C_Stop()
161 {
162 1 unsigned int t = I2C_STOP_WAIT_VALUE;
163 1 I2C_SDA = 0;
164 1 I2C_Delay();
165 1 I2C_SCL = 1;
166 1 I2C_Delay();
167 1 I2C_SDA = 1;
168 1 I2C_Delay();
169 1 while ( --t != 0 ); //在下一次产生Start之前,要加一定的延时
170 1 }
171
172
173 /*
174 函数:I2C_Puts()
175 功能:主机通过I2C总线向从机发送多个字节的数据
176 参数:
177 SlaveAddr:从机地址(高7位是从机地址,最低位是写标志0)
178 SubAddr:从机的子地址
179 Size:数据的字节数
C51 COMPILER V7.09 I2C 12/05/2007 16:14:14 PAGE 4
180 *dat:要发送的数据
181 返回:
182 0:发送成功
183 1:在发送过程中出现异常
184 */
185 bit I2C_Puts(unsigned char SlaveAddr, unsigned char SubAddr, unsigned char Size, char *dat)
186 {
187 1 //检查长度
188 1 if ( Size == 0 ) return 0;
189 1 //确保从机地址最低位是0
190 1 SlaveAddr &= 0xFE;
191 1 //启动I2C总线
192 1 I2C_Start();
193 1 //发送从机地址
194 1 I2C_Write(SlaveAddr);
195 1 if ( I2C_GetAck() )
196 1 {
197 2 I2C_Stop();
198 2 return 1;
199 2 }
200 1 //发送子地址
201 1 I2C_Write(SubAddr);
202 1 if ( I2C_GetAck() )
203 1 {
204 2 I2C_Stop();
205 2 return 1;
206 2 }
207 1 //发送数据
208 1 do
209 1 {
210 2 I2C_Write(*dat++);
211 2 if ( I2C_GetAck() )
212 2 {
213 3 I2C_Stop();
214 3 return 1;
215 3 }
216 2 } while ( --Size != 0 );
217 1 //发送完毕,停止I2C总线,并返回结果
218 1 I2C_Stop();
219 1 return 0;
220 1 }
221
222
223 /*
224 函数:I2C_Put()
225 功能:主机通过I2C总线向从机发送1个字节的数据
226 参数:
227 SlaveAddr:从机地址(高7位是从机地址,最低位是写标志0)
228 SubAddr:从机的子地址
229 dat:要发送的数据
230 返回:
231 0:发送成功
232 1:在发送过程中出现异常
233 */
234 bit I2C_Put(unsigned char SlaveAddr, unsigned char SubAddr, char dat)
235 {
236 1 return I2C_Puts(SlaveAddr,SubAddr,1,&dat);
237 1 }
238
239
240 /*
241 函数:I2C_Gets()
C51 COMPILER V7.09 I2C 12/05/2007 16:14:14 PAGE 5
242 功能:主机通过I2C总线从从机接收多个字节的数据
243 参数:
244 SlaveAddr:从机地址(高7位是从机地址,最低位是读标志1)
245 SubAddr:从机的子地址
246 Size:数据的字节数
247 *dat:保存接收到的数据
248 返回:
249 0:接收成功
250 1:在接收过程中出现异常
251 */
252 bit I2C_Gets(unsigned char SlaveAddr, unsigned char SubAddr, unsigned char Size, char *dat)
253 {
254 1 //检查长度
255 1 if ( Size == 0 ) return 0;
256 1 //确保从机地址最低位是0
257 1 SlaveAddr &= 0xFE; //确保最低位是0
258 1 //启动I2C总线
259 1 I2C_Start();
260 1 //发送从机地址
261 1 I2C_Write(SlaveAddr);
262 1 if ( I2C_GetAck() )
263 1 {
264 2 I2C_Stop();
265 2 return 1;
266 2 }
267 1 //发送子地址
268 1 I2C_Write(SubAddr);
269 1 if ( I2C_GetAck() )
270 1 {
271 2 I2C_Stop();
272 2 return 1;
273 2 }
274 1 //发送重复起始条件
275 1 I2C_Start();
276 1 //发送从机地址
277 1 SlaveAddr |= 0x01;
278 1 I2C_Write(SlaveAddr);
279 1 if ( I2C_GetAck() )
280 1 {
281 2 I2C_Stop();
282 2 return 1;
283 2 }
284 1 //接收数据
285 1 for (;;)
286 1 {
287 2 *dat++ = I2C_Read();
288 2 if ( --Size == 0 )
289 2 {
290 3 I2C_PutAck(1);
291 3 break;
292 3 }
293 2 I2C_PutAck(0);
294 2 }
295 1 //接收完毕,停止I2C总线,并返回结果
296 1 I2C_Stop();
297 1 return 0;
298 1 }
299
300
301 /*
302 函数:I2C_Get()
303 功能:主机通过I2C总线从从机接收1个字节的数据
C51 COMPILER V7.09 I2C 12/05/2007 16:14:14 PAGE 6
304 参数:
305 SlaveAddr:从机地址(高7位是从机地址,最低位是读标志1)
306 SubAddr:从机的子地址
307 *dat:保存接收到的数据
308 返回:
309 0:接收成功
310 1:在接收过程中出现异常
311 */
312 bit I2C_Get(unsigned char SlaveAddr, unsigned char SubAddr, char *dat)
313 {
314 1 return I2C_Gets(SlaveAddr,SubAddr,1,dat);
315 1 }
316
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 415 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 1 16
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 + -