stm32 硬件i2c bug的I2C为什么会有bug

2014年7月 硬件/嵌入开发大版内专家分月排行榜第二
2013年10月 硬件/嵌入开发大版内专家分月排行榜第三2013年6月 硬件/嵌入开发大版内专家分月排行榜第三2013年3月 硬件/嵌入开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。查看: 2983|回复: 4
STM32模拟I2C为什么接收不到应答信号?
主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
在线时间0 小时
STM32模拟I2C与ad5161通讯,为什么接收不到应答信号?
&* 函数名:void I2C_GPIO_Config(void)
&* 描述 : I2C管脚初始化
&* 输入 &:无
&* 输出 : 无
void I2C_GPIO_Config(void)//void I2C_GPIO_Init(void)
GPIO_InitTypeDef GPIO_InitS
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
// PB6-I2C1_SCL、PB7-I2C1_SDA&
//初始化SCL管脚
GPIO_InitStructure.GPIO_Pin = &SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//PP; &
GPIO_Init(SCL_PORT, &GPIO_InitStructure);
//初始化SDA管脚
GPIO_InitStructure.GPIO_Pin = &SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//;
GPIO_Init(SDA_PORT, &GPIO_InitStructure);
&* 函数名: void I2C_delay(void)
&* 描述 : 短暂延时
&* 输入 : 无
&* 输出 : 无
&* 说明 : 内部定义的i可以优化速度,经测试最低到5还能写入
static void I2C_delay(void)
& & u16 i=2000;&
& & while(i)&
& & & & i--;&
static void I2C_delay1(void)
& & u16 i=500;&
& & while(i)&
& & & & i--;&
void I2C_Delay(vu32 nCount)
& for(; nCount != 0; nCount--);
&* 函数名: bool I2C_Start(void)
&* 描述 : 起始信号
&* 输入 : 无
&* 输出 : TRUE : 成功
& & & & & & & & & & &FALSE : 失败
&* 说明 : IIC起始信号定义为当SCL为高电平(HIGH)时,SDA线从高到低的跳变
bool I2C_Start(void)
SDA_OUT();
//sda线输出
& & SDA_H;
& & I2C_delay();
& & SCL_H;
& & I2C_delay();
& & SDA_L;
& & I2C_delay();
& & SCL_L;
//钳住I2C总线,准备发送或接收数据,避免在SCL为高电平期间,再次发出起始信号或者停止信号
& & //I2C_delay();
return TRUE;
&* 函数名: static void I2C_Stop(void)
&* 描述 : 终止信号
&* 输入 : 无
&* 输出 : 无
&* 说明 :IIC停止信号定义为当SCL为高电平(HIGH)时,SDA线从低到高的跳变 &
void I2C_Stop(void)
SDA_OUT(); //sda线输出
& & SCL_L;
& & I2C_delay();
& & SCL_H;
& & I2C_delay();
& & SDA_H;
& & I2C_delay();
&* 函数名: static void I2C_Ack(void)
&* 描述 :产生应答信号 ,主机从从机读取数据后,向从机发出应答信号
&* 输入 : 无
&* 输出 : 无
&* 说明 : 主机在接收到从机的数据后,向从机返回一个应答信号,
&继续通信,在SCL为高电平器件,SDA一直保持低电平表示应答
static void &I2C_Ack(void)
& & SCL_L;
SDA_OUT();
// & &I2C_delay();
& & SDA_L;
& & I2C_delay();
& & SCL_H;
& & I2C_delay();
& & SCL_L; //SCL再输出低电平,保证在SCL为高电平期间,SDA始终保持高电平,表示应答信号
& & //I2C_delay();
&* 函数名: void I2C_NoAck(void)
&* 描述 : 不产生应答信号,主机接收到从机的数据后,不发出应答信号&
&* 输入 : 无
&* 输出 : 无
&* 说明 :&
static void I2C_NoAck(void)
& & SCL_L;
SDA_OUT();
& & SDA_H;
& & I2C_delay();
& & SCL_H;
& & I2C_delay();
& & SCL_L;
& &//SCL再次输出低电平,保证SCL为高时,SDA一直为高
& & //I2C_delay();
&* 函数名: bool I2C_WaitAck(void)
&* 描述 : 等待应答信号
&* 输入 : 无
&* 输出 : TRUE : 有应答
& & & & & & & & & & &FALSE : 无应答
&* 说明 : IIC通信时,接收到数据,从机(Slave)会发出ACK信号,
&一般是一个低电平 信号出现在SDA线上,若主机检测到,则认为此次通信成功
static bool I2C_WaitAck(void) &&
& & u16 ucErrTime=0;
&//释放总线
I2C_delay1();
& & I2C_delay1();
while(READ_SDA)
ucErrTime++;
if(ucErrTime&500)
I2C_Stop();
& & & &return FALSE;
& & SCL_L;
// & &I2C_delay();
& & return TRUE; &
&* 函数名: static void I2C_SendByte(u8 SendByte)&
&* 描述 : 发送一个字节
&* 输入 : SendByte : 字节数据
&* 输出 : 无
&* 说明 : 数据从高位到低位
static void I2C_SendByte(u8 SendByte)&
SDA_OUT();
SCL_L; //拉低时钟开始数据传输
& & for(i=0;i&8;i++)&
& & & & if((SendByte&&i)&0x80)
& & & & & & SDA_H;
& & & & else
& & & & & & SDA_L; &&
& & & & I2C_delay();
& & & & I2C_delay();
& & & & I2C_delay();
&* 函数名: static u8 I2C_ReceiveByte(void)&
&* 描述 : 读取一个字节
&* 输入 : 无&
&* 输出 : 字节数据
&* 说明 : ReceiveByte : 数据从高位到低位
u8 I2C_ReceiveByte(u8 ack) &
& & u8 i,ReceiveByte=0;
// I2C_delay();
& & for(i=0;i&8;i++)
& & & & SCL_L;
& & & & I2C_delay();
& & & & SCL_H;
ReceiveByte&&=1;
// & & & &I2C_delay();
& & & & if(READ_SDA)
& & & & & & ReceiveByte++;
& & & & I2C_delay();
I2C_NoAck(); //不回应
I2C_Ack();
& & return ReceiveB
* 函数名: Delay(vu32 nCount)
&* 描述 : 延时函数&
&* 输入 :&
&* 说明 :&
void Delay_ms(vu32 nCount)
& for(; nCount != 0; nCount--);
&* 函数名: bool I2C_WriteByte(u8 DeviceAddress, u16 cmd, u8 SendByte)
&* 描述 : 写入1字节数据 &
&* 输入 : DeviceAddress : 器件地址
cmd:控制命令
SendByte : 要写入数据
& & & & & & & & & & &
&* 输出 : TRUE : 成功
& & & & & & & & & & &FALSE : 失败
&* 说明 :&
bool I2C_WriteByte(u8 DeviceAddress, u16 cmd, u8 SendByte)
& & I2C_Start();
I2C_SendByte(DeviceAddress);//写入器件地址
& & I2C_WaitAck(); &&
& & I2C_SendByte(cmd); & //写入控制命令
& & I2C_WaitAck(); &&
& & I2C_SendByte(SendByte);
&//写入数据
& & I2C_WaitAck();&
& & I2C_Stop();&
& & return TRUE;
&* 函数名: bool I2C_ReadByte(u8* pBuffer, & u8 length, & & u16 ReadAddress, &u8 DeviceAddress)
&* 描述 : 读出1串数据
&* 输入 : pBuffer : 要读取数据缓冲区指针
& & & & & &length : 待读取长度 &
& & & & & & & & & & &DeviceAddress : 器件地址
&* 输出 : TRUE : 成功
& & & & & & & & & & &FALSE : 失败
&* 说明 : 跨页写入1串数据
u8 I2C_ReadByte(u8 DeviceAddress)
u8 pBuffer=0xFE;
I2C_Start();
& & I2C_SendByte(DeviceAddress);//设置器件地址 0x59
& I2C_WaitAck();
& & I2C_delay();
pBuffer=I2C_ReceiveByte(0);
&//接收数据无应答位
& & I2C_Stop();
& & return pB
主题帖子精华
金钱115446
在线时间871 小时
主题帖子精华
在线时间281 小时
回复【楼主位】小悦怡然:
---------------------------------
好好看IIC通讯协议去
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
主题帖子精华
高级会员, 积分 713, 距离下一级还需 287 积分
在线时间0 小时
IIC器件读数据不是你这么写的吧,即使读一个字节函数,一般也是先写地址-应答-写控制字-应答-停止-再起始-(写读的地址)-(应答)-写数据,只少你最后一个函数有问题,IIC时序模拟部分没看出什么问题
主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
在线时间0 小时
回复【4楼】hechao3225:
---------------------------------
程序没有错,是硬件问题,换了块ad5161就好了。谢谢你的回答。
Powered bySTM32 硬件I2C bug解决方案 - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 5834|回复: 13
STM32 硬件I2C bug解决方案
在线时间0 小时
主题帖子好友
新手上路, 积分 47, 距离下一级还需 3 积分
新手上路, 积分 47, 距离下一级还需 3 积分
古人说的一句,方法总比问题多,真的一点儿也不假
硬件有问题,怕啥,大神来支招,就算是先天性bug,一样搞定
最近看到一个硬件I2C bug解决的方案,特来与大家分享
大神从芯片底层分析了为啥会有这样的bug,真大神也
后面给出的解决方案如下:
发送时:
开始,发送写地址,器件应答,清ADDR,一字节数据到写DR,硬件把DR数据写入到DSR,当DSR传输完毕时,DR也为空,BTF置位,这时我们再写一字节数据到DR,如此循环,最后一次BTF置位的时候发送P或者重起始(R)。这样操作,“硬件把DR数据写入到DSR”执行的时间是我们可以预料的,不存在上面提及的冲突问题。
1、接收一个字节:按照ST给的方法。开始,发送读地址,器件应答,清ADDR前软件下拉SCL,写完NACK、STOP和DR后软件再释放SCL。RxNE时读DR。
2、接收两个字节:也是按照ST的方法。开始,发送读地址,器件应答,设置POS和ACK,下拉SCL,清ADDR,设置NACK,释放SCL。BTF时,软件拉低SCL,发送STOP,读DR,释放SCL,再读DR。
3、接收两个以上字节:开始,发送读地址,器件应答,直接清ADDR。BTF时,读DR一次。再BTF,再读DR一次,如此循环。倒数第二次BTF时设置NACK(注意DR和DSR各有一字节的数据),读DR一次。再等到最后一次BTF时,软件拉低SCL,发送STOP,读DR,释放SCL,再读DR。具体的,还是靠大家自己去参悟啦
在线时间137 小时
主题帖子好友
金牌会员, 积分 1811, 距离下一级还需 3189 积分
金牌会员, 积分 1811, 距离下一级还需 3189 积分
这种帖子含金量蛮高的,支持多发这种帖子
在线时间0 小时
主题帖子好友
新手上路, 积分 47, 距离下一级还需 3 积分
新手上路, 积分 47, 距离下一级还需 3 积分
这种帖子含金量蛮高的,支持多发这种帖子
斑斑见笑了
在线时间799 小时
ST金币3024
主题帖子好友
之前调试的时候,就是多个字节发送的时候太麻烦了,用他的硬件发送的时候,看见勘误手册上写着,当发送一个字节的时候应该怎么办,两个字节的时候应该怎么办,实在是太麻烦了,后来直接使用模拟算了。
不考虑多主机的时候,模拟也是不错的选择。
在线时间0 小时
主题帖子好友
新手上路, 积分 47, 距离下一级还需 3 积分
新手上路, 积分 47, 距离下一级还需 3 积分
之前调试的时候,就是多个字节发送的时候太麻烦了,用他的硬件发送的时候,看见勘误手册上写着,当发送一个 ...
确实啊,模拟的,可移植性很强。硬件I2C,想规避bug的话,确实很蛋疼,不知道ST怎么想的,哈哈
在线时间799 小时
ST金币3024
主题帖子好友
确实啊,模拟的,可移植性很强。硬件I2C,想规避bug的话,确实很蛋疼,不知道ST怎么想的,哈哈 ...
之前看过一个帖子,不知道是不是真的,说的是ST不愿意花钱买NXP的专利,于是自己做了这么一套。不知道是不是真的。
如果不想买专利的话,像ATMEL那样换一个名字不就好了
在线时间0 小时
主题帖子好友
新手上路, 积分 47, 距离下一级还需 3 积分
新手上路, 积分 47, 距离下一级还需 3 积分
之前看过一个帖子,不知道是不是真的,说的是ST不愿意花钱买NXP的专利,于是自己做了这么一套。不知道是 ...
坑。。。还好有大神支招,哈哈
在线时间799 小时
ST金币3024
主题帖子好友
坑。。。还好有大神支招,哈哈
另起一个名字,就叫什么ST-LINK,哈哈哈
在线时间0 小时
主题帖子好友
新手上路, 积分 47, 距离下一级还需 3 积分
新手上路, 积分 47, 距离下一级还需 3 积分
另起一个名字,就叫什么ST-LINK,哈哈哈
全都是Link,也凌乱了,哈哈
在线时间601 小时
主题帖子好友
顶一下,,,,,,,,,,
站长推荐 /2
,同时大家也可以下载电子版学习
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered by

我要回帖

更多关于 stm32脉冲bug 的文章

 

随机推荐