OpenEdv-开源电子网

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

IIC_Wait_Ack()函数中为什么把sda设成输入以后还执行IIC_SDA=1

[复制链接]

24

主题

60

帖子

0

精华

初级会员

Rank: 2

积分
186
金钱
186
注册时间
2012-12-19
在线时间
3 小时
发表于 2013-3-10 22:32:25 | 显示全部楼层 |阅读模式
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;  
}


IIC_Wait_Ack()函数中为什么把sda设成输入以后还执行IIC_SDA=1,这个时候sda端口相当于一个输入口,把sda设成1没用把


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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-10 23:09:00 | 显示全部楼层
回复【楼主位】zjtzlqr:
---------------------------------
提供一个上拉。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2011-9-23
在线时间
4 小时
发表于 2013-3-11 09:47:12 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我也有这个疑问,IIC_SDA=1等于是PAout()=1,但是这个时候寄存器被设置为输入状态,这个PAout()还起作用吗,具体是怎么个机理……
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-11 11:12:07 | 显示全部楼层
回复【3楼】gxuan1:
---------------------------------
学会STM32的IO先。
好好看看我们的教程,按键输入实验。就知道在输入模式下,ODR可能有什么用!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2011-9-23
在线时间
4 小时
发表于 2013-3-11 11:44:21 | 显示全部楼层
恩,我再去看看……
回复 支持 反对

使用道具 举报

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2011-9-23
在线时间
4 小时
发表于 2013-3-11 11:54:54 | 显示全部楼层
又看了看代码,这样写的原因如下:
#define Aout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
我之前一直是单独设置ODR的,看来ODR和PXout()就是一回事……
回复 支持 反对

使用道具 举报

24

主题

60

帖子

0

精华

初级会员

Rank: 2

积分
186
金钱
186
注册时间
2012-12-19
在线时间
3 小时
 楼主| 发表于 2013-3-15 09:11:51 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
看了一下stm32的中文参考手册,里面的端口位配置表里面又讲到上拉下拉输入模式中ODR寄存器为0代表下拉输入,ODR寄存器为1代表上拉输入,这里在等待ACK的时候确实需要把odr寄存器置1.这样的画如果从器件有发送ack的话mcu就会收到
回复 支持 反对

使用道具 举报

头像被屏蔽

52

主题

440

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1237
金钱
1237
注册时间
2013-1-9
在线时间
151 小时
发表于 2013-3-15 15:21:16 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-15 16:56:06 | 显示全部楼层
回复【8楼】hexboot:
---------------------------------
我们的是模拟IIC,里面很多的delay_us,这个,就可以设置频率啊。频率是指SCK的频率,控制delay自然就控制sck频率了啊
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2013-9-6
在线时间
0 小时
发表于 2013-9-6 13:12:46 | 显示全部楼层
 while(READ_SDA)这句话是什么意思?   #define READ_SDA   PBin(11)  
                         是不是说检测到PB11有输入然后READ_SDA就为真?还是有其它意思?如果方便的话,顺便解释一下其下面的  if  函数的的意义,初学,求教~~~~~

{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-9-6 14:04:38 | 显示全部楼层
就是判断PB11是不是1,如果是,执行下面的语句,如果不是,就跳过while了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2013-9-6
在线时间
0 小时
发表于 2013-9-6 15:06:03 | 显示全部楼层
回复【11楼】正点原子:
---------------------------------
谢谢!还有,我觉得ucErrorTime这个参数的作用,是不是说如果在一段时间内PB11一直是1的话,ucErrorTime会自增到250,即代表从机一直没有发送应答信号? 而且,IIC_Wait_Ack()这个函数是有返回值的,严谨一点来操作是不是得每次等待应答之后都得判断一次应答码是否接收到,以确定线上器件的状态?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-9-6 21:23:47 | 显示全部楼层
回复【12楼】猫先生:
---------------------------------
你觉得改成什么样比较好?麻烦贴一下代码,就楼主这个函数。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2016-6-7
在线时间
27 小时
发表于 2016-11-30 20:24:12 | 显示全部楼层
你好,这个地方我也有不解,能不能帮忙解释一下,也你这个疑问
回复 支持 反对

使用道具 举报

2

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2016-6-7
在线时间
27 小时
发表于 2016-11-30 20:24:48 | 显示全部楼层
IIC_Wait_Ack()函数中为什么把sda设成输入以后还执行IIC_SDA=1,这个时候sda端口相当于一个输入口,把sda设成1没用把
回复 支持 反对

使用道具 举报

2

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2016-6-7
在线时间
27 小时
发表于 2016-11-30 20:32:27 | 显示全部楼层
[mw_shl_code=applescript,true]//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).M4同M3类似,只是寄存器地址变了.
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414   
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14   
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入[/mw_shl_code]


这里面其实是赋值给那个位带的地址
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-6-8
在线时间
4 小时
发表于 2017-6-8 15:37:13 | 显示全部楼层
zjtzlqr 发表于 2013-3-15 09:11
回复【4楼】正点原子:
---------------------------------
看了一下stm32的中文参考手册,里面的端口位配置 ...

为什么只有把ODR寄存器置1,从器件有发送ack的话,mcu才能收到啊?
回复 支持 反对

使用道具 举报

13

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
144
金钱
144
注册时间
2016-9-3
在线时间
26 小时
发表于 2017-6-8 16:41:10 | 显示全部楼层
同样有疑问
SDA_IN();      //SDA设置为输入  
IIC_SDA=1;delay_us(1);
在输入模式下让SDA输出1有作用吗?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-18 18:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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