找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2126|回复: 3
打印 上一主题 下一主题
收起左侧

I2C通讯软件模拟 老是报错

[复制链接]
跳转到指定楼层
楼主
ID:377512 发表于 2018-7-22 19:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define AT24C02_ADDR 0xa0;

  6. /*I2C IO口定义*/
  7. sbit SDA = P2^0;
  8. sbit SCL = P2^1;

  9. /*5us延时*/
  10. void delay_5us()
  11. {
  12.   _nop_();
  13. }

  14. /*1ms延时*/
  15. void delay(uint z)
  16. {
  17.     uint x,y;
  18.     for(x = z; x > 0; x-- )
  19.           for(y = 114; y > 0; y-- )
  20.           ;
  21. }

  22. /*I2C初始化*/
  23. void I2C_init()
  24. {
  25.     SCL = 1;
  26.         _nop_();
  27.         SDA = 1;
  28.         _nop_();
  29. }

  30. /*I2C开始信号*/
  31. void I2C_Start()
  32. {
  33.   SCL = 1;
  34.   _nop_();
  35.   SDA = 1;
  36.   delay_5us();
  37.   SDA = 0;
  38.   delay_5us();
  39. }

  40. /*I2C停止信号*/
  41. void I2C_Stop()
  42. {
  43.    SDA = 0;
  44.    _nop_();
  45.    SCL = 1;
  46.    delay_5us();
  47.    SDA = 1;
  48.    delay_5us();
  49. }

  50. /*主机发送应答*/
  51. void Master_ACK(bit i) //bit i 控制应答或者非应答
  52. {
  53.            SCL = 0;
  54.          _nop_();
  55.          if(i)
  56.          {
  57.            SDA = 0;
  58.          }
  59.          else
  60.          {
  61.            SDA = 1;
  62.          }
  63.          _nop_();
  64.          SCL = 1;  
  65.          delay_5us();
  66.          SCL = 0;
  67.          _nop_();
  68.          SDA = 1;
  69.          _nop_();
  70. }

  71. /*检测从机应答*/
  72. bit Test_ACK()
  73. {
  74.   SCL = 1;
  75.   delay_5us();
  76.   if(SDA)
  77.   {
  78.     SCL = 0;
  79.         _nop_();
  80.         I2C_Stop();
  81.         return(0);//从机无应答返回0
  82.   }
  83.   else
  84.   {
  85.     SCL = 0;
  86.         _nop_();
  87.         return(1);//从机应答返回1
  88.   }
  89. }

  90. /*发送一个字节*/
  91. void I2C_send_byte(uchar byte)
  92. {
  93.    uchar i;
  94.    for(i = 0; i < 8; i++)
  95.     {
  96.             SCL = 0;
  97.                 _nop_();
  98.                 if(byte & 0x80)//表达式成立 说明byte最高位为1
  99.                 {
  100.                     SDA = 1;
  101.                         _nop_();
  102.                 }
  103.                 else
  104.                 {
  105.                    SDA = 0;
  106.                    _nop_();
  107.                 }
  108.                 SCL = 1;
  109.                 _nop_();
  110.                 byte <<= 1;
  111.         }
  112.         SCL = 0;//拉低时钟总线 允许从机的应答信号
  113.         _nop_();
  114.         SDA = 1;//主机释放数据总线 让从机控制
  115.     _nop_();
  116. }

  117. /*接收一个字节*/
  118. uchar I2C_read_byte()
  119. {
  120.     uchar dat,i;
  121.         SCL = 0;//拉低时钟总线 允许从机控制SDA
  122.         _nop_();
  123.         SDA = 1;//释放数据总线
  124.         _nop_();
  125.     for (i = 0 ; i < 8 ; i++)
  126.         {
  127.              SCL = 1;//拉高时钟总线 允许主机读数据
  128.                  _nop_();
  129.                  if(SDA)
  130.                  {
  131.                     dat |= 0x01;
  132.                  }
  133.                  else
  134.                  {
  135.                     dat &= 0xfe;
  136.                  }
  137.                  _nop_();
  138.                  SCL = 0;//允许主机发送应答
  139.                  _nop_();
  140.                  if(i < 7)
  141.                  {
  142.                     dat =dat << 1;
  143.                  }
  144.         }
  145.         return(dat);
  146. }
  147. /*I2C发送数据*/
  148. bit I2C_TransmitData(uchar ADDR,DAT)
  149. {
  150.      I2C_Start();
  151.            I2C_send_byte(AT24C02_ADDR+0);

  152.          if(!Test_ACK())
  153.          {
  154.            return(0);//停止传送
  155.      }
  156.          I2C_send_byte(ADDR);
  157.      if(!Test_ACK())
  158.          {
  159.            return(0);//停止传送
  160.      }
  161.          I2C_send_byte(DAT);
  162.          if(!Test_ACK())
  163.          {
  164.            return(0);//停止传送
  165.      }
  166.          I2C_Stop();
  167.          return(1);//传送完成
  168. }
  169. /*I2C接收数据*/
  170. uchar I2C_ReceiveData(uchar ADDR)
  171. {
  172.         uchar DAT;
  173.         I2C_Start();
  174.         I2C_send_byte(AT24C02_ADDR+0);
  175.         if(!Test_ACK())
  176.          {
  177.            return(0);//停止传送
  178.      }
  179.          I2C_send_byte(ADDR);
  180.          if(!Test_ACK())
  181.          {
  182.            return(0);//停止传送
  183.      }
  184.         Master_ACK(0);        //主机非应答
  185.         I2C_Start();
  186.         I2C_send_byte(AT24C02_ADDR+1);
  187.          if(!Test_ACK())
  188.          {
  189.            return(0);//停止传送
  190.      }
  191.          DAT = I2C_read_byte();
  192.          Master_ACK(0);
  193.          I2C_Stop();
  194.          return(DAT);

  195. }
  196. void main()
  197. {
  198.            I2C_init();
  199.         if(!I2c_TransmitDATA(255,0xfe))
  200.         {
  201.            P1 = 0;//数据传送失败
  202.         }
  203.         delay(5);
  204.         P1 = I2C_ReceiveData(255);
  205.         while(1);
  206. }
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2018-7-23 06:29 | 只看该作者
1.  #define AT24C02_ADDR 0xa0; 多了一个分号。
2. bit I2C_TransmitData(uchar ADDR,DAT)  与 if(!I2c_TransmitDATA(255,0xfe)) 的函数名大小写不一致。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:377512 发表于 2018-7-23 07:53 来自手机 | 只看该作者
大佬 是怎么发现的 我怎么发现不了
回复

使用道具 举报

地板
ID:375092 发表于 2018-7-28 10:22 | 只看该作者
你的bit I2C_TransmitData(uchar ADDR,DAT)这个函数DAT不能直接写,加了分号之后还需要加uchar,应该写成bit I2C_TransmitData(uchar ADDR,uchar DAT)

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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