OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 18147|回复: 15

IIC中IIC_Wait_Ack(void)函数的问题

[复制链接]

12

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2012-5-17
在线时间
0 小时
发表于 2012-8-20 18:37:17 | 显示全部楼层 |阅读模式
版主的程序如下:
 u8 IIC_Wait_Ack(void)
{
 u8 ucErrTime=0;
 SDA_IN();      //SDA设置为输入 
 IIC_SDA=1;delay_us(1);   
 IIC_SCL=1;delay_us(1); 
 while(READ_SDA)
 {
  ucErrTime++;
  if(ucErrTime>250)
  {
   IIC_Stop();
   return 1;
  }
 }
 IIC_SCL=0;//时钟输出0    
 return 0; 
}

这是个有返回值的函数,但在后面的程序中,返回的值是什么都是无所谓的,不管有应答的时候返回的是0或者1都能运行。 那为什么不能把这个函数定义成void的类型呢?
而且我尝试过后也确实不行。
C语言能力有点薄弱 ,希望各位大虾帮忙回答。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2012-8-11
在线时间
0 小时
发表于 2012-8-20 19:21:51 | 显示全部楼层
这个返回值是判断 ACK 信号的,ACK 为1时返回1,为0时返回0,ACK为0才正常
回复 支持 反对

使用道具 举报

12

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2012-5-17
在线时间
0 小时
 楼主| 发表于 2012-8-20 21:18:41 | 显示全部楼层
回复【2楼】Alexinx:
---------------------------------
但即使改成
 u8 IIC_Wait_Ack(void)
{
 u8 ucErrTime=0;
 SDA_IN();      //SDA设置为输入  
 IIC_SDA=1;delay_us(1);    
 IIC_SCL=1;delay_us(1);  
 while(READ_SDA)
 {
  ucErrTime++;
  if(ucErrTime>250)
  {
   IIC_Stop();
   return 0;
  }
 }
 IIC_SCL=0;//时钟输出0     
 return1;  


也是能正常工作的啊。 只是编程的时候这么定义的吧。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-20 23:09:11 | 显示全部楼层
你要用到连续写模式才知道问题.
单词写,有无都影响不大.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

12

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2012-5-17
在线时间
0 小时
 楼主| 发表于 2012-8-21 13:36:47 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
我感觉SDA的低电平信号也就是ACK一般都会有的啊,因为我EEPROM的读写从来没出现过问题。那我把 
if(ucErrTime>250) 
  { 
   IIC_Stop(); 
   return 0; 
  } 
这段去掉后,为什么就不能正常运行了呢?
在while里等到它的ACK来不就行了吗? 反正总会来的
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-21 14:00:21 | 显示全部楼层
回复【5楼】pope_hxj:
---------------------------------
按照你的思路,你的理解,自己写一个IIC协议吧.(完全不用我们提供的代码)
这东西又不是什么很复杂的.
能用就OK.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2012-6-25
在线时间
0 小时
发表于 2012-8-28 11:07:40 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
原子哥 我移植了你的模拟I2c读取温度,,, 为什么总是等不到应答信号  应答一直是ack=1,我也看了硬件什么就是找不到问题,,,难道时序会出问题吗?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-28 11:38:47 | 显示全部楼层
我用一直没啥问题哦,你得找找是不是你的操作有问题,或者你的硬件有问题。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-8-16
在线时间
3 小时
发表于 2012-8-29 13:03:37 | 显示全部楼层
 有点小疑惑 一直想不明白
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;  //为低时允许SDA电平变化
SDA_OUT(); //输出 (输出是相对于24C16么?)
IIC_SDA=0;  //这里是不是就是应答信号啊
delay_us(2); //延时的用处是什么
IIC_SCL=1;  //置高,有必要么
delay_us(2);
IIC_SCL=0; 
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-29 13:23:06 | 显示全部楼层
回复【9楼】枫过云叶:
---------------------------------
这个代码是标准IIC应答的。
不是针对24c16.
不懂,请看IIC协议文档。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

13

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2012-11-17
在线时间
18 小时
发表于 2012-12-15 22:45:23 | 显示全部楼层
回复【5楼】pope_hxj:
回复【4楼】正点原子: --------------------------------- 我感觉SDA的低电平信号也就是ACK一般都会有的啊,因为我EEPROM的读写从来没出现过问题。那我把  if(ucErrTime>250)    {     IIC_Stop();     return 0;    }  这段去掉后,为什么就不能正常运行了呢? 在while里等到它的ACK来不就行了吗? 反正总会来的
---------------------------------
你说的是一般都会来,要是如果出了什么故障,导致器件没发送应答信号,即SDA一直为高电平,程序就会卡在这里无法出来而死机,真正的程序是不允许出现这样的情况。加入ucErrTime>250后,如果主器件在一定时间没有收到从器件的应答信号,程序还是会自动跳出,不会卡死。
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2012-12-15 23:17:22 | 显示全部楼层
回复【11楼】bj2008wyou:
你说的是一般都会来,要是如果出了什么故障,导致器件没发送应答信号,即SDA一直为高电平,程序就会卡在这里无法出来而死机,真正的程序是不允许出现这样的情况。加入ucErrTime>250后,如果主器件在一定时间没有收到从器件的应答信号,程序还是会自动跳出,不会卡死。
---------------------------------

ACK或NACK都是合法的格式。
业余程序玩家。
回复 支持 反对

使用道具 举报

69

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
469
金钱
469
注册时间
2014-6-21
在线时间
0 小时
发表于 2014-8-24 10:29:53 | 显示全部楼层
回复【4楼】正点原子:
-------------------------------
后面的程序也没对返回1的情况进行处理啊?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-8-26 00:52:56 | 显示全部楼层
回复【13楼】mengxiao1980:
---------------------------------
不处理就不处理了,没一定要处理。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
140
金钱
140
注册时间
2014-8-31
在线时间
33 小时
发表于 2014-9-6 10:16:45 | 显示全部楼层
回复【12楼】ofourme:
---------------------------------
解疑老师解除了我的疑惑,真的很感谢!
回复 支持 反对

使用道具 举报

9

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
169
金钱
169
注册时间
2020-11-24
在线时间
38 小时
发表于 2021-2-1 10:19:57 | 显示全部楼层
正点原子 发表于 2014-8-26 00:52
回复【13楼】mengxiao1980:
---------------------------------
不处理就不处理了,没一定要处理。

原子您好,我现在遇到的问题就是我用IIC通信,每次读取一个字节信息时,都会返回应答失败,程序如下
  1. // 在MAG3110指定寄存器地址读出一个字节数据
  2. // ReadAddr:开始读数的寄存器地址 0-255
  3. // 返回值,读到的数据
  4. u8 MAG3110_ReadOneByte(u16 ReadAddr)
  5. {
  6.         u8 temp = 0; // 存储读到的数据
  7.         IIC_Start(); // 发送起始信号
  8.         IIC_Send_Byte(MAG3110_IIC_WRITE_ADDRESS); // 写操作地址
  9.         if(IIC_Wait_Ack())
  10.         {
  11.                 IIC_Stop();
  12.                 printf("ACK Failed!\r\n");
  13.                 return 0;
  14.         }
  15.         IIC_Send_Byte(ReadAddr);
  16.         if(IIC_Wait_Ack())
  17.         {
  18.                 IIC_Stop();
  19.                 printf("ACK Failed!\r\n");
  20.                 return 0;
  21.         }
  22.         IIC_Start(); // 发送新的起始信号
  23.         IIC_Send_Byte(MAG3110_IIC_READ_ADDRESS); // 发送从机地址+1(读操作地址)
  24.         if(IIC_Wait_Ack())
  25.         {
  26.                 IIC_Stop();
  27.                 printf("ACK Failed!\r\n");
  28.                 return 0;
  29.         }
  30.         temp = IIC_Read_Byte(0); // 读取从机数据,读完之后从机不产生应答
  31.         IIC_Stop(); // 停止信号
  32.         return temp;
  33.        
  34. }
复制代码
每次写入单个字节如果不判断从设备是否应答成功,那读出来的数据如何保证正确性?我看了您上面的回复,说写入单个字节无需判断是否应答成功?这是什么原因呢???谢谢。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 10:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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