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