📄 51
字号:
213 void iic_start(void)
214 { //时钟保持高,数据线从高到低一次跳变,I2C通信开始
215 1 SDA = 1;
216 1 SCL = 1;
217 1 delayNOP(); // 延时5us
218 1 SDA = 0;
219 1 delayNOP();
220 1 SCL = 0;
221 1 }
222 //-------------------------------------------------------------------
223 // 函数名称: iic_stop()
224 // 函数功能: 停止I2C总线数据传送子程序
225 //-------------------------------------------------------------------
226 void iic_stop(void)
227 {
228 1 SDA = 0; //时钟保持高,数据线从低到高一次跳变,I2C通信停止
229 1 SCL = 1;
230 1 delayNOP();
231 1 SDA = 1;
232 1 delayNOP();
233 1 SCL = 0;
234 1 }
235 //------------------------------------------------------------------
236 // 函数名称: iicInit_()
237 // 函数功能: 初始化I2C总线子程序
238 //------------------------------------------------------------------
239 void iicInit(void)
240 {
C51 COMPILER V8.02 PCF8591 04/08/2010 23:02:02 PAGE 5
241 1 SCL = 0;
242 1 iic_stop();
243 1 }
244 //-------------------------------------------------------------------
245 // 函数名称: slave_ACK
246 // 函数功能: 从机发送应答位子程序
247 //-------------------------------------------------------------------
248 void slave_ACK(void)
249 {
250 1 SDA = 0;
251 1 SCL = 1;
252 1 delayNOP();
253 1 SCL = 0;
254 1 }
255 //-------------------------------------------------------------------
256 // 函数名称: slave_NOACK
257 // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
258 //-------------------------------------------------------------------
259 void slave_NOACK(void)
260 {
261 1 SDA = 1;
262 1 SCL = 1;
263 1 delayNOP();
264 1 SDA = 0;
265 1 SCL = 0;
266 1 }
267 //-------------------------------------------------------------------
268 // 函数名称: check_ACK
269 // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
270 //-------------------------------------------------------------------
271 void check_ACK(void)
272 {
273 1 SDA = 1; // 将p1.1设置成输入,必须先向端口写1
274 1 SCL = 1;
275 1 askflag = 0;
276 1 delayNOP();
277 1 if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志askflag
278 1 askflag = 1;
279 1 SCL = 0;
280 1 }
281 //-------------------------------------------------------------------
282 // 函数名称: IICSendByte
283 // 入口参数: ch
284 // 函数功能: 发送一个字节
285 //-------------------------------------------------------------------
286 void IICSendByte(uchar ch)
287
288 {
289 1 unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位
290 1
291 1 while(n--)
292 1 {
293 2 if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
294 2 {
295 3 SDA = 1; // 传送位1
296 3 SCL = 1;
297 3 delayNOP();
298 3 // SDA = 0;
299 3 SCL = 0;
300 3 }
301 2 else
302 2 {
C51 COMPILER V8.02 PCF8591 04/08/2010 23:02:02 PAGE 6
303 3 SDA = 0; // 否则传送位0
304 3 SCL = 1;
305 3 delayNOP();
306 3 SCL = 0;
307 3 }
308 2 ch = ch<<1; // 数据左移一位
309 2 }
310 1 }
311 //-------------------------------------------------------------------
312 // 函数名称: IICreceiveByte
313 // 返回接收的数据
314 // 函数功能: 接收一字节子程序
315 //-------------------------------------------------------------------
316 uchar IICreceiveByte(void)
317 {
318 1 uchar idata n=8; // 从SDA线上读取一上数据字节,共八位
319 1 uchar tdata=0;
320 1 while(n--)
321 1 {
322 2 SDA = 1;
323 2 SCL = 1;
324 2 tdata =tdata<<1; //左移一位
325 2 if(SDA == 1)
326 2 tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1
327 2 else
328 2 tdata = tdata&0xfe; // 否则数据的最后一位置0
329 2 SCL = 0;
330 2 }
331 1
332 1 return(tdata);
333 1 }
334 //-------------------------------------------------------------------
335 // 函数名称: ADC_PCF8591
336 // 入口参数: controlbyte控制字
337 // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
338 //-------------------------------------------------------------------
339 void ADC_PCF8591(uchar controlbyte)
340 {
341 1 uchar idata receive_da,i=0;
342 1
343 1 iic_start();
344 1
345 1 IICSendByte(PCF8591_WRITE); //控制字
346 1 check_ACK();
347 1 if(askflag == 1)
348 1 {
349 2 SystemError = 1;
350 2 return;
351 2 }
352 1
353 1 IICSendByte(controlbyte); //控制字
354 1 check_ACK();
355 1 if(askflag == 1)
356 1 {
357 2 SystemError = 1;
358 2 return;
359 2 }
360 1
361 1 iic_start(); //重新发送开始命令
362 1 IICSendByte(PCF8591_READ); //控制字
363 1 check_ACK();
364 1 if(askflag == 1)
C51 COMPILER V8.02 PCF8591 04/08/2010 23:02:02 PAGE 7
365 1 {
366 2 SystemError = 1;
367 2 return;
368 2 }
369 1
370 1 IICreceiveByte(); //空读一次,调整读顺序
371 1 slave_ACK(); //收到一个字节后发送一个应答位
372 1
373 1 while(i<4)
374 1 {
375 2 receive_da=IICreceiveByte();
376 2 receivebuf[i++]=receive_da;
377 2 slave_ACK(); //收到一个字节后发送一个应答位
378 2 }
379 1 slave_NOACK(); //收到最后一个字节后发送一个非应答位
380 1 iic_stop();
381 1 }
382
383 //液晶刷新
384
385 void lcd_flash(void)
386 {
387 1 unsigned char i = 0;
388 1 lcd_pos(0); //设置显示位置为第一行的第1个字符
389 1 while(dis4[i] != '\0')
390 1 { //显示字符
391 2 lcd_wdat(dis4[i]);
392 2 i++;
393 2 }
394 1 lcd_pos(0x40); //设置显示位置为第二行第1个字符
395 1 i = 0;
396 1 while(dis5[i] != '\0')
397 1 {
398 2 lcd_wdat(dis5[i]); //显示字符
399 2 i++;
400 2 }
401 1 }
402
403
404 //********************************************************
405 //函数功能:定时器T0的相关程序
406 //*******************************************************
407 #define T0start() TR0 = 1; //启动定时器T0开始运行
408 #define T0off() TR1 = 0; //关闭T0定时器
409 #define T2start() TR2 = 1; //开启T2计数器
410 #define T2off() TR2 = 0; //关闭T2计数器
411 //unsigned int x;
412 unsigned char num;
413 //t0初始化
414 void intt0init()
415 {
416 1 TMOD = 0x01; //使用定时器T0
417 1 TH0 = (65536-50000)/256; //将定时器计时时间设定为50毫秒 //=50000微秒=50毫秒
418 1 TL0 = (65536-50000)%256;
419 1 EA = 1; //开启总中断
420 1 ET0 = 1; //定时器T0中断允许
421 1
422 1 T0start();
423 1 T2start();
424 1 }
425 //t0中断
426
C51 COMPILER V8.02 PCF8591 04/08/2010 23:02:02 PAGE 8
427 void interserve(void ) interrupt 1 using 1
428 {
429 1 T0off(); //关闭定时器T0 50MS一次中断
430 1 EA = 0;
431 1 num++;
432 1 if(num == 40) //够20次中断,即1秒钟进行一次检测结果采样 // 1.086*2 0.59us
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -