📄 pcf8591.lst
字号:
247 1 SCL = 0;
248 1 }
249 //-------------------------------------------------------------------
250 // 函数名称: check_ACK
251 // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
252 //-------------------------------------------------------------------
253 void check_ACK(void)
254 {
255 1 SDA = 1; // 将p1.1设置成输入,必须先向端口写1
256 1 SCL = 1;
257 1 F0 = 0;
258 1 delayNOP();
259 1 if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0
260 1 F0 = 1;
261 1 SCL = 0;
262 1 }
263 //-------------------------------------------------------------------
264 // 函数名称: IICSendByte
265 // 入口参数: ch
266 // 函数功能: 发送一个字节
267 //-------------------------------------------------------------------
268 void IICSendByte(uchar ch)
269
270 {
271 1 unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位
272 1
273 1 while(n--)
274 1 {
275 2 if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
276 2 {
277 3 SDA = 1; // 传送位1
278 3 SCL = 1;
279 3 delayNOP();
280 3 // SDA = 0;
281 3 SCL = 0;
282 3 }
283 2 else
284 2 {
285 3 SDA = 0; // 否则传送位0
286 3 SCL = 1;
287 3 delayNOP();
288 3 SCL = 0;
289 3 }
290 2 ch = ch<<1; // 数据左移一位
291 2 }
292 1 }
293 //-------------------------------------------------------------------
294 // 函数名称: IICreceiveByte
295 // 返回接收的数据
296 // 函数功能: 接收一字节子程序
297 //-------------------------------------------------------------------
298 uchar IICreceiveByte(void)
299 {
300 1 uchar idata n=8; // 从SDA线上读取一上数据字节,共八位
301 1 uchar tdata=0;
302 1 while(n--)
C51 COMPILER V8.05a PCF8591 12/04/2006 11:20:24 PAGE 6
303 1 {
304 2 SDA = 1;
305 2 SCL = 1;
306 2 tdata =tdata<<1; //左移一位
307 2 if(SDA == 1)
308 2 tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1
309 2 else
310 2 tdata = tdata&0xfe; // 否则数据的最后一位置0
311 2 SCL = 0;
312 2 }
313 1
314 1 return(tdata);
315 1 }
316 //-------------------------------------------------------------------
317 // 函数名称: DAC_PCF8591
318 // 入口参数: slave_add从机地址,n要发送的数据个数
319 // 函数功能: 发送n位数据子程序
320 //-------------------------------------------------------------------
321 void DAC_PCF8591(uchar controlbyte,uchar w_data)
322 {
323 1
324 1 iic_start(); // 启动I2C
325 1 delayNOP();
326 1
327 1 IICSendByte(PCF8591_WRITE); // 发送地址位
328 1 check_ACK(); // 检查应答位
329 1 if(F0 == 1)
330 1 {
331 2 SystemError = 1;
332 2 return; // 若非应答,置错误标志位
333 2 }
334 1 IICSendByte(controlbyte&0x77); //Control byte
335 1 check_ACK(); //检查应答位
336 1 if(F0 == 1)
337 1 {
338 2 SystemError = 1;
339 2 return; // 若非应答,置错误标志位
340 2 }
341 1 IICSendByte(w_data); //data byte
342 1 check_ACK(); // 检查应答位
343 1 if(F0 == 1)
344 1 {
345 2 SystemError = 1;
346 2 return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
347 2 }
348 1 iic_stop(); // 全部发完则停止
349 1 delayNOP();
350 1 delayNOP();
351 1 delayNOP();
352 1 delayNOP();
353 1 }
354 //-------------------------------------------------------------------
355 // 函数名称: ADC_PCF8591
356 // 入口参数: controlbyte控制字
357 // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
358 //-------------------------------------------------------------------
359 void ADC_PCF8591(uchar controlbyte)
360 {
361 1 uchar idata receive_da,i=0;
362 1
363 1 iic_start();
364 1
C51 COMPILER V8.05a PCF8591 12/04/2006 11:20:24 PAGE 7
365 1 IICSendByte(PCF8591_WRITE); //控制字
366 1 check_ACK();
367 1 if(F0 == 1)
368 1 {
369 2 SystemError = 1;
370 2 return;
371 2 }
372 1
373 1 IICSendByte(controlbyte); //控制字
374 1 check_ACK();
375 1 if(F0 == 1)
376 1 {
377 2 SystemError = 1;
378 2 return;
379 2 }
380 1
381 1 iic_start(); //重新发送开始命令
382 1 IICSendByte(PCF8591_READ); //控制字
383 1 check_ACK();
384 1 if(F0 == 1)
385 1 {
386 2 SystemError = 1;
387 2 return;
388 2 }
389 1
390 1 IICreceiveByte(); //空读一次,调整读顺序
391 1 slave_ACK(); //收到一个字节后发送一个应答位
392 1
393 1 while(i<4)
394 1 {
395 2 receive_da=IICreceiveByte();
396 2 receivebuf[i++]=receive_da;
397 2 slave_ACK(); //收到一个字节后发送一个应答位
398 2 }
399 1 slave_NOACK(); //收到最后一个字节后发送一个非应答位
400 1 iic_stop();
401 1 }
402 //-------------------------------------------------------------------
403 // 函数名称: main
404 // 函数功能: 主程序
405 //-------------------------------------------------------------------
406 main()
407 {
408 1 uchar i,l;
409 1 delay(10); //延时
410 1 lcd_init(); //初始化LCD
411 1
412 1 lcd_pos(0); //设置显示位置为第一行的第1个字符
413 1 i = 0;
414 1 while(dis4[i] != '\0')
415 1 { //显示字符
416 2 lcd_wdat(dis4[i]);
417 2 i++;
418 2 }
419 1
420 1 lcd_pos(0x40); //设置显示位置为第二行第1个字符
421 1 i = 0;
422 1 while(dis5[i] != '\0')
423 1 {
424 2 lcd_wdat(dis5[i]); //显示字符
425 2 i++;
426 2 }
C51 COMPILER V8.05a PCF8591 12/04/2006 11:20:24 PAGE 8
427 1
428 1 while(1)
429 1 {
430 2 iicInit(); //I2C总线初始化
431 2 ADC_PCF8591(0x04);
432 2
433 2 if(SystemError == 1) //有错误,重新来
434 2 {
435 3 iicInit(); //I2C总线初始化
436 3 ADC_PCF8591(0x04);
437 3 }
438 2
439 2 for(l=0;l<4;l++)
440 2 {
441 3 show_value(receivebuf[0]); //显示通道0
442 3 lcd_pos(0x02);
443 3 lcd_wdat(dis[2]); //整数位显示
444 3 lcd_pos(0x04);
445 3 lcd_wdat(dis[1]); //第一位小数显示
446 3 lcd_pos(0x05);
447 3 lcd_wdat(dis[0]); //第二位小数显示
448 3
449 3 show_value(receivebuf[1]); //显示通道1
450 3 lcd_pos(0x0b);
451 3 lcd_wdat(dis[2]); //整数位显示
452 3 lcd_pos(0x0d);
453 3 lcd_wdat(dis[1]); //第一位小数显示
454 3 lcd_pos(0x0e);
455 3 lcd_wdat(dis[0]); //第二位小数显示
456 3
457 3 show_value(receivebuf[2]); //显示通道2
458 3 lcd_pos(0x42);
459 3 lcd_wdat(dis[2]); //整数位显示
460 3 lcd_pos(0x44);
461 3 lcd_wdat(dis[1]); //第一位小数显示
462 3 lcd_pos(0x45);
463 3 lcd_wdat(dis[0]); //第二位小数显示
464 3
465 3 show_value(receivebuf[3]); //显示通道3
466 3 lcd_pos(0x4b);
467 3 lcd_wdat(dis[2]); //整数位显示
468 3 lcd_pos(0x4d);
469 3 lcd_wdat(dis[1]); //第一位小数显示
470 3 lcd_pos(0x4e);
471 3 lcd_wdat(dis[0]); //第二位小数显示
472 3
473 3 iicInit(); //I2C总线初始化
474 3 DAC_PCF8591(0x40,receivebuf[0]); //D/A输出
475 3
476 3 if(SystemError == 1) //有错误,重新来
477 3 {
478 4 iicInit(); //I2C总线初始化
479 4 DAC_PCF8591(0x40,receivebuf[0]); //D/A输出
480 4 }
481 3
482 3 //delay(50); //延时
483 3 }
484 2
485 2 }
486 1 }
C51 COMPILER V8.05a PCF8591 12/04/2006 11:20:24 PAGE 9
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 861 ----
CONSTANT SIZE = 34 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 8 1
IDATA SIZE = 4 4
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 + -