找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1334|回复: 1
收起左侧

51单片机+PCF8591仿真不正确,但是烧录到单片机中是可以的,I2C有问题?

[复制链接]
ID:1028584 发表于 2022-5-22 01:09 | 显示全部楼层 |阅读模式
如题,使用PCF8591的AD模式时,仿真结果是正确的,能够读到正确的输出,但是使用DA功能时就不对了,使用DA时,设置输出2.5V以上能够正常输出,设置输出2.5V以下就不能正常输出。
另外在使用AD模式时,控制字不能设置为0x00,讲道理我用AD的时候模拟输出端口使能我应该是可以置零的啊,但是置零就不对。。。
贴出原理图和部分代码,文件在附件中,求各位大佬解惑
PS.同样的问题也出现在EEPROM ATC02中,也是仿真不正确烧录到单片机中正确。。。
这两个芯片都是I2C通信,难道是I2C的问题?

PCF8591.zip

84.92 KB, 下载次数: 9

代码及仿真文件

回复

使用道具 举报

ID:1028584 发表于 2022-5-22 01:13 | 显示全部楼层
帖子长度有限制,现将部分单片机代码贴上
  1. #include <REGX52.H>
  2. #include "delay.h"

  3. //这里的延时都可以去掉,是用来调试代码的时候方便分析的

  4. /*********************
  5. /*@brief        该文件定义了I2C的6个时序,可以直接调用,
  6. /*@param        6个时序分别为起始、发送字节、接收应答、接收字节、发送应答、终止
  7. /*@retval
  8. *********************/

  9. //单片机实际连接引脚
  10. sbit scl = P3^4;
  11. sbit sda = P3^5;

  12. /*********************
  13. /*@brief        I2C起始条件,SCL高电平期间,SDA从高电平切换到低电平
  14. /*@param        无
  15. /*@retval        无
  16. *********************/
  17. void I2C_start() {
  18.     sda =1;
  19.     scl = 1;
  20.     delay10us();
  21.     sda =0;
  22.     delay10us();
  23.     scl =0;
  24. }

  25. /*********************
  26. /*@brief        I2C终止条件,SCL高电平期间,SDA从低电平切换到高电平
  27. /*@param        无
  28. /*@retval        无
  29. *********************/
  30. void I2C_stop() {
  31.     sda = 0;
  32.     scl = 1;
  33.     delay10us();
  34.     sda = 1;
  35. }

  36. /*********************
  37. /*@brief        I2C发送一个字节,SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,
  38.                                         从机将在SCL高电平期间读取数据位,SCL高电平期间SDA不允许数据变化,
  39. /*@param        要发送的字节
  40. /*@retval        无
  41. *********************/
  42. void I2C_sendByte(unsigned char Byte) {
  43.     int i;
  44.     for(i=0; i<8; i++) {
  45.         sda = Byte&(0x80>>i);
  46.         delay10us();
  47.         scl = 1;
  48.         delay10us();//这里可能比较重要?
  49.         scl = 0;
  50.     }
  51. }

  52. /*********************
  53. /*@brief        I2C接收一个字节,主机在接收之前需要释放SDA
  54.                                         SCL低电平期间,从机将数据位依次放到SDA线上(高位在前),然后拉高SCL,
  55.                                         主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许数据变化
  56. /*@param        无
  57. /*@retval        接收到的数据
  58. *********************/
  59. unsigned char I2C_receiveByte() {
  60.     unsigned char Byte=0x00;
  61.     int i;
  62.     sda =1;
  63.     for(i=0; i<8; i++) {
  64.         scl=1;
  65.         if(sda)(Byte|=(0x80>>i));
  66.         delay10us();
  67.         scl=0;
  68.         delay10us();
  69.     }
  70.     return Byte;
  71. }

  72. /*********************
  73. /*@brief        I2C发送应答
  74. /*@param        数据0表示应答,数据1表示非应答
  75. /*@retval        无
  76. *********************/
  77. void I2C_sendACK(bit ack) {
  78.     sda = ack;
  79.     delay10us();
  80.     scl = 1;
  81.     scl =0;
  82. }

  83. /*********************
  84. /*@brief        I2C接收应答,主机在接收之前,需要释放SDA
  85. /*@param        数据0表示应答,数据1表示非应答
  86. /*@retval        接收到的应答标志
  87. *********************/
  88. bit I2C_receiveACK() {
  89.     bit ack;
  90.     sda =1;
  91.     delay10us();
  92.     scl =1;
  93.     ack = sda;
  94.     delay10us();
  95.     scl =0;
  96.     return ack;
  97. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表