📄 viic_c51.lst
字号:
C51 COMPILER V7.04 VIIC_C51 03/05/2006 15:29:20 PAGE 1
C51 COMPILER V7.04, COMPILATION OF MODULE VIIC_C51
OBJECT MODULE PLACED IN VIIC_C51.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE VIIC_C51.c BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /********************************************************************
2 VIIC_C51.C
3 此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据
4 及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的
5 与用户程序连接并扩展.....
6
7 注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作
8 一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ)
9 SomeNop():100k-10uS
10 400k-2.5uS
11 ********************************************************************/
12
13
14 #include "viic_c51.h"
15 #include <reg52.h>
16 #include <intrins.h>
17
18
19 #define SomeNop() _nop_()//;_nop_() /*定义空指令*/
20
21 /* 常,变量定义区 */
22
23 /*端口位定义*/
24 sbit SDA=P1^5; /*模拟I2C数据传送位*/
25 sbit SCL=P1^4; /*模拟I2C时钟控制位*/
26
27 /*状态标志*/
28 bit ack; /*应答标志位*/
29 /*******************************************************************
30 起动总线函数
31 函数原型: void Start_I2c();
32 功能: 启动I2C总线,即发送I2C起始条件.
33
34 ********************************************************************/
35 void Start_I2c()
36 {
37 1 SDA=1; /*发送起始条件的数据信号*/
38 1 SomeNop();
39 1 SCL=1;
40 1 SomeNop(); /*起始条件建立时间大于4.7us,延时*/
41 1 SomeNop();
42 1 SomeNop();
43 1 SomeNop();
44 1 SomeNop();
45 1 SDA=0; /*发送起始信号*/
46 1 SomeNop(); /* 起始条件锁定时间大于4μs*/
47 1 SomeNop();
48 1 SomeNop();
49 1 SomeNop();
50 1 SomeNop();
51 1 SCL=0; /*钳住I2C总线,准备发送或接收数据 */
52 1 SomeNop();
53 1 SomeNop();
54 1 }
55
C51 COMPILER V7.04 VIIC_C51 03/05/2006 15:29:20 PAGE 2
56
57
58
59 /*******************************************************************
60 结束总线函数
61 函数原型: void Stop_I2c();
62 功能: 结束I2C总线,即发送I2C结束条件.
63
64 ********************************************************************/
65 void Stop_I2c()
66 {
67 1 SDA=0; /*发送结束条件的数据信号*/
68 1 SomeNop(); /*发送结束条件的时钟信号*/
69 1 SCL=1; /*结束条件建立时间大于4μs*/
70 1 SomeNop();
71 1 SomeNop();
72 1 SomeNop();
73 1 SomeNop();
74 1 SomeNop();
75 1 SDA=1; /*发送I2C总线结束信号*/
76 1 SomeNop();
77 1 SomeNop();
78 1 SomeNop();
79 1 SomeNop();
80 1 }
81
82
83
84
85 /*******************************************************************
86 字节数据传送函数
87 函数原型: void SendByte(uchar c);
88 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
89 此状态位进行操作.(不应答或非应答都使ack=0 假)
90 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
91 ********************************************************************/
92 void SendByte(uchar c)
93 {
94 1 uchar timeout;
95 1
96 1 uchar BitCnt;
97 1
98 1 for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/
99 1 {
100 2 if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/
101 2 else SDA=0;
102 2 SomeNop();
103 2 SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/
104 2 SomeNop();
105 2 SomeNop(); /*保证时钟高电平周期大于4μs*/
106 2 SomeNop();
107 2 SomeNop();
108 2 SomeNop();
109 2 SCL=0;
110 2 }
111 1
112 1 SomeNop();
113 1 SomeNop();
114 1 SDA=1; /*8位发送完后释放数据线,准备接收应答位*/
115 1 SomeNop();
116 1 SomeNop();
117 1 SCL=1;
C51 COMPILER V7.04 VIIC_C51 03/05/2006 15:29:20 PAGE 3
118 1 SomeNop();
119 1 SomeNop();
120 1 SomeNop();
121 1
122 1 for(timeout=0;timeout<250;timeout++)
123 1 {
124 2 if(SDA==1)ack=0;
125 2 else ack=1; /*判断是否接收到应答信号*/
126 2
127 2 if(ack==1)break;
128 2 }
129 1
130 1 SCL=0;
131 1 SomeNop();
132 1 SomeNop();
133 1 }
134
135
136
137
138
139
140 /*******************************************************************
141 字节数据传送函数
142 函数原型: uchar RcvByte();
143 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
144 发完后请用应答函数。
145 ********************************************************************/
146 uchar RcvByte()
147 {
148 1 uchar retc;
149 1 uchar BitCnt;
150 1
151 1 retc=0;
152 1 SDA=1; /*置数据线为输入方式*/
153 1 for(BitCnt=0;BitCnt<8;BitCnt++)
154 1 {
155 2 SomeNop();
156 2 SCL=0; /*置时钟线为低,准备接收数据位*/
157 2 SomeNop();
158 2 SomeNop(); /*时钟低电平周期大于4.7μs*/
159 2 SomeNop();
160 2 SomeNop();
161 2 SomeNop();
162 2 SCL=1; /*置时钟线为高使数据线上数据有效*/
163 2 SomeNop();
164 2 SomeNop();
165 2 retc=retc<<1;
166 2 if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
167 2 SomeNop();
168 2 SomeNop();
169 2 }
170 1 SCL=0;
171 1 SomeNop();
172 1 SomeNop();
173 1 return(retc);
174 1 }
175
176
177
178
179 /********************************************************************
C51 COMPILER V7.04 VIIC_C51 03/05/2006 15:29:20 PAGE 4
180 应答子函数
181 原型: void Ack_I2c(bit a);
182
183 功能:主控器进行应答信号,(可以是应答或非应答信号)
184 ********************************************************************/
185 void Ack_I2c(bit a)
186 {
187 1
188 1 if(a==0)SDA=0; /*在此发出应答或非应答信号 */
189 1 else SDA=1;
190 1 SomeNop();
191 1 SomeNop();
192 1 SomeNop();
193 1 SCL=1;
194 1 SomeNop();
195 1 SomeNop(); /*时钟低电平周期大于4μs*/
196 1 SomeNop();
197 1 SomeNop();
198 1 SomeNop();
199 1 SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/
200 1 SomeNop();
201 1 SomeNop();
202 1 }
203
204
205 /*******************************************************************
206 向有子地址器件发送多字节数据函数
207 函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
208 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
209 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
210 如果返回1表示操作成功,否则操作有误。
211 注意: 使用前必须已结束总线。
212 ********************************************************************/
213 bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
214 {
215 1 xdata uchar i;
216 1 uchar ch;
217 1
218 1 //Stop_I2c();//先释放总线
219 1
220 1 Start_I2c(); /*启动总线*/
221 1 SendByte(sla); /*发送器件地址*/
222 1 if(ack==0)return(0);
223 1 SendByte(suba); /*发送器件子地址*/
224 1 if(ack==0)return(0);
225 1
226 1 for(i=0;i<no;i++)
227 1 {
228 2 ch=*s;
229 2 SendByte(ch); /*发送数据*/
230 2 if(ack==0)return(0);
231 2 s++;
232 2 }
233 1 Stop_I2c(); /*结束总线*/
234 1 return(1);
235 1 }
236
237
238
239
240
241
C51 COMPILER V7.04 VIIC_C51 03/05/2006 15:29:20 PAGE 5
242
243
244 /*******************************************************************
245 向有子地址器件读取多字节数据函数
246 函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
247 功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
248 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
249 如果返回1表示操作成功,否则操作有误。
250 注意: 使用前必须已结束总线。
251 ********************************************************************/
252 bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
253 {
254 1 xdata uchar i;
255 1 uchar ch;
256 1
257 1 //Stop_I2c();//先释放总线
258 1
259 1 Start_I2c(); /*启动总线*/
260 1 SendByte(sla); /*发送器件地址*/
261 1 if(ack==0)return(0);
262 1 SendByte(suba); /*发送器件子地址*/
263 1 if(ack==0)return(0);
264 1
265 1 Start_I2c();
266 1 SendByte(sla+1);
267 1 if(ack==0)return(0);
268 1
269 1 for(i=0;i<no-1;i++)
270 1 {
271 2 ch=RcvByte(); /*发送数据*/
272 2 *s=ch;
273 2 Ack_I2c(0); /*发送就答位*/
274 2 s++;
275 2 }
276 1 *s=RcvByte();
277 1 Ack_I2c(1); /*发送非应位*/
278 1 Stop_I2c(); /*结束总线*/
279 1 return(1);
280 1 }
281
282
283
284
285
286
287
288
289
290
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 335 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- 2
PDATA SIZE = ---- ----
DATA SIZE = ---- 12
IDATA SIZE = ---- ----
BIT SIZE = 1 1
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -