[问答] 新手被I2C总线弄得头疼 请大神帮忙分析下 下面两个同为应答函数代码区别

[复制链接]
实习生
发表于 2017-8-8 12:27:31   486 查看 3 回复 只看该作者 倒序浏览
分享
一个是有参数的应答函数,一个是没有参数的应答函数
另问:在应答过程中当SCL为高电平时,SDA的电平是不是根据数据的接收情况自动决定是高电平还是低电平?
代码一中参数的作用是什么?
每次发送一个字节结束后,都要用这样的应答函数吗?
void Ack_I2c(bit a)     //a作为应答标志
{  
  if(a==0)sda=0;              /*在此发出应答或非应答信号 */
  else sda=1;      /*0为发出应答,1为非应答信号 */
  _nop_();
  _nop_();
  _nop_();      
  scl=1;
  _nop_();
  _nop_();                    /*时钟低电平周期大于4μs*/
  _nop_();
  _nop_();
  _nop_();  
  scl=0;                     /*清时钟线,住I2C总线以便继续接收*/
  _nop_();
  _nop_();   
}


bit Ask()
{
bit ack_bit;
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
ack_bit=SDA;
SCL=0;
reurn ack_bit;
}
奖励2积分
Night1ngale 2017-8-8 本帖最后由 Night1ngale 于 2017-8-10 23:34 编辑

1.第一个函数是单片机是否要向设备产生IIC应答信号的函数,第二个函数是单片机判断设备是否产生了应答信号的函数。

应答信号的两种情况:
(1)主机等待应答,设备产生应答,这是第二个函数的功能。
这个时候,主机的SDA信号线拉高,SCL线拉高,主机等待设备的SDA信号线产生低电平信号,检测一段时间后,如果主机检测到了设备产生的低电平信号,那么主机SCL拉低,返回0,那么,我们就知道设备产生应答信号了,证明连接上了。
如果检测一段时间后,没有检测到设备产生低电平信号,那么主机SCL拉低,返回1,那么,我们就知道设备没有产生应答信号了。
(2)主机产生应答,设备等待应答,这是第一个函数的功能。
这个时候,设备的SDA信号线会拉高,SCL线拉低(这个过程我们不需要去管设备怎么操作的),这时候,函数中的参数a就是用来决定主机要不要产生应答信号的标志,如果a=0,证明我们需要主机产生应答信号,这时候主机的SDA线拉低,设备会检测到这个低电平信号,那么设备就知道,已经跟主机连接上了。如a=1,那么证明我们不需要主机产生应答信号,这时候主机的SDA线保持在高电平状态,那么设备检测不到低电平信号,设备就知道,主机没有反应了。

不知道这么说你明白吗?不明白的话,可以再问我。

2.可以这么说,SDA线上的信号如果是高电平,那么有低电平进来的时候,会自动拉低,就是你说的那样,由数据决定的。

3.第一个函数中的参数的功能在1里面已经说了,不清楚可以继续问我。

4.不是每发送一个字节,就需要产生一个应答信号。假如你的设备是8位数据的,那么发送一个数据,需要一次发送8个字节,在一次数据发送结束后,也就是在发送完8个字节之后,再进入等待应答或者产生应答的状态。

纯手打,欢迎你有不清楚的地方,继续问我。
实习生
发表于 2017-8-8 12:27:32  
本帖最后由 Night1ngale 于 2017-8-10 23:34 编辑

1.第一个函数是单片机是否要向设备产生IIC应答信号的函数,第二个函数是单片机判断设备是否产生了应答信号的函数。

应答信号的两种情况:
(1)主机等待应答,设备产生应答,这是第二个函数的功能。
这个时候,主机的SDA信号线拉高,SCL线拉高,主机等待设备的SDA信号线产生低电平信号,检测一段时间后,如果主机检测到了设备产生的低电平信号,那么主机SCL拉低,返回0,那么,我们就知道设备产生应答信号了,证明连接上了。
如果检测一段时间后,没有检测到设备产生低电平信号,那么主机SCL拉低,返回1,那么,我们就知道设备没有产生应答信号了。
(2)主机产生应答,设备等待应答,这是第一个函数的功能。
这个时候,设备的SDA信号线会拉高,SCL线拉低(这个过程我们不需要去管设备怎么操作的),这时候,函数中的参数a就是用来决定主机要不要产生应答信号的标志,如果a=0,证明我们需要主机产生应答信号,这时候主机的SDA线拉低,设备会检测到这个低电平信号,那么设备就知道,已经跟主机连接上了。如a=1,那么证明我们不需要主机产生应答信号,这时候主机的SDA线保持在高电平状态,那么设备检测不到低电平信号,设备就知道,主机没有反应了。

不知道这么说你明白吗?不明白的话,可以再问我。

2.可以这么说,SDA线上的信号如果是高电平,那么有低电平进来的时候,会自动拉低,就是你说的那样,由数据决定的。

3.第一个函数中的参数的功能在1里面已经说了,不清楚可以继续问我。

4.不是每发送一个字节,就需要产生一个应答信号。假如你的设备是8位数据的,那么发送一个数据,需要一次发送8个字节,在一次数据发送结束后,也就是在发送完8个字节之后,再进入等待应答或者产生应答的状态。

纯手打,欢迎你有不清楚的地方,继续问我。
回复 点赞 举报
实习生
发表于 2017-8-11 14:13:54    楼主|

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
你的回答我明白了,感谢解惑,我还有一个问题,也是关于应答信号的
Void responds()
{
    uchar i=0;
    SCL=1;
    delay();
    while((SDA==1)&&(i<255))
             i++;
    SCL=0;
    delay();
}
这个应答函数没有返回值,是设备给主机的应答吗?这个函数,是不管从机有没有给出应答(while语句的作用),程序都会进行下去的意思吗?还有如果从机没有发出应答信号,主机会自动产生终止信号(不用代码)使传送结束吗?
回复 点赞 举报
实习生
发表于 2017-8-12 22:00:13  
哇, 这个函数我还真是没看懂,应该是主机等待应答的函数,但是不应该没有返回值呀。我觉得正确的代码应该是这样:
bit responds()
{
     uchar i=0;
     SDA=1
     _nop_();
     _nop_();
     SCL=1;
     _nop_();
     _nop_();
     delay();
     while((SDA==1)&&(i<255))
              i++;
     if(i>=255)
          return 1;
     else
          return 0
     SCL=0;
     delay();
}
这样只有从机在主机的255个机器时钟内应答了,就可以检测到。
你原来那个函数我也没看懂,如果运行的话,其实没有任何结果,只是延迟的作用。
回复 点赞 举报
高级模式
您需要登录后才可以回帖 登录 | 注册
关闭

站长推荐 上一条 /9 下一条

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

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

我的提问

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区