找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于I2C数据有效性的疑问

[复制链接]
跳转到指定楼层
楼主
ID:318173 发表于 2018-7-27 21:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个字节发送函数我看得明白是符合数据位的有效性性规定,一字节数据一次一位发送,以SCL=1保证数据有效性,之后将SCL置0,当需要再发送一位时SCL=0,符合数据有效性

可是这个字节接收函数首先他就让SCL=0,不是很懂,我的初步理解结合两个函数一起看,当字节发送函数时由主机控制SCL变化,发送一位上SDA,让SCL=1,先保证他数据有效传输,然后SCL=0,同上,之后再发送一位时,SCL=0,因此SDA可以变化,对于字节接收函数,此时由从机控制SCL变化,当主机发送完数据丛机准备接收时,首先打开SCL=0,保证一位一位接收时SDA可以变化,当有一位在SDA上时,让SCL=1,保证传输到从机这的数据是有效的。请大佬指证

至于最初的字节接收函数开始的SDA=1,和最后的SCL=0不是很懂。

请大佬指教一下,不是很懂,希望大佬能详细讲解下,这里想了很久卡了很久,希望大佬可以对比着这两个函数讲讲数据传输过程。

  1. /*******************************************************************
  2.                  字节数据接收函数               
  3. 函数原型: UCHAR  I2C_RcvByte();
  4. 功能:        用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  5.           发完后请用应答函数应答从机。  
  6. ********************************************************************/   
  7. unsigned char   I2C_RcvByte()
  8. {
  9.   unsigned char  retc=0,i;
  10.   sda=1;                     /*置数据线为输入方式*/      (不是很明白???)
  11.   for(i=0;i<8;i++)
  12.       {
  13.         _nop_();           
  14.         scl=0;                  /*置时钟线为低,准备接收数据位*/
  15.         _nop_();
  16.         _nop_();                 /*时钟低电平周期大于4.7μs*/
  17.         _nop_();
  18.         _nop_();
  19.         _nop_();
  20.         scl=1;                  /*置时钟线为高使数据线上数据有效*/
  21.         _nop_();
  22.         _nop_();
  23.         retc=retc<<1;
  24.         if(sda==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
  25.         _nop_();
  26.         _nop_();
  27.       }
  28.   scl=0;      (不是很懂???)
  29.   _nop_();
  30.   _nop_();
  31.   return(retc);
  32. }



  33. /*******************************************************************
  34.                  字节数据发送函数               
  35. 函数原型: void  I2C_SendByte(UCHAR c);
  36. 功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  37.           此状态位进行操作.(不应答或非应答都使ack=0)     
  38.            发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  39. ********************************************************************/
  40. void  I2C_SendByte(unsigned char  c)
  41. {
  42. unsigned char  i;

  43. for(i=0;i<8;i++)  /*要传送的数据长度为8位*/
  44.     {
  45.      if((c<<i)&0x80)sda=1;   /*判断发送位*/
  46.        else  sda=0;               
  47.      _nop_();
  48.      scl=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  49.       _nop_();
  50.       _nop_();             /*保证时钟高电平周期大于4μs*/
  51.       _nop_();
  52.       _nop_();
  53.       _nop_();         
  54.      scl=0;
  55.     }

  56.     _nop_();
  57.     _nop_();
  58.     sda=1;                /*8位发送完后释放数据线,准备接收应答位*/
  59.     _nop_();
  60.     _nop_();   
  61.     scl=1;
  62.     _nop_();
  63.     _nop_();
  64.     _nop_();
  65.     if(sda==1)ack=0;     
  66.        else ack=1;        /*判断是否接收到应答信号*/
  67.     scl=0;
  68.     _nop_();
  69.     _nop_();
  70. }
复制代码


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

使用道具 举报

沙发
ID:68356 发表于 2018-7-29 03:46 | 只看该作者
接收函数一开始SDA置一,是让从机来决定总线电平,不产生线与,使用这个接收函数时,主机是发送了接收指令给从机,从机送出数据,当从机接收到发送指令后,就会把数据的第一位放到总线上,这个时候的SCL就是发送指令的最后一位的结束,就是低电平,所以接收函数的SCL以低电平开始,每产生一个高电平,在其下降沿之后,从机再放第二位数据到总线上。。。好像是这么回事

评分

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

查看全部评分

回复

使用道具 举报

板凳
ID:380500 发表于 2018-7-29 15:28 | 只看该作者
我也想知道,新手学习
回复

使用道具 举报

地板
ID:111634 发表于 2018-7-29 16:34 | 只看该作者
看IIC信号传送要求,理解就行了。
回复

使用道具 举报

5#
ID:318173 发表于 2018-7-29 16:39 | 只看该作者
xiuyueyuan2013 发表于 2018-7-29 03:46
接收函数一开始SDA置一,是让从机来决定总线电平,不产生线与,使用这个接收函数时,主机是发送了接收指令 ...

那接收函数的数据位有效性怎么看呢?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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